/*
 *
 *    Copyright (c) 2022 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

#import <Foundation/Foundation.h>

#import "MTRAttributeCacheContainer_Internal.h"
#import "MTRBaseClusters_internal.h"
#import "MTRBaseDevice.h"
#import "MTRBaseDevice_Internal.h"
#import "MTRCallbackBridge_internal.h"
#import "MTRCluster_internal.h"
#import "MTRCommandPayloadsObjc.h"
#import "MTRStructsObjc.h"

#include <lib/support/CHIPListUtils.h>
#include <platform/CHIPDeviceLayer.h>
#include <type_traits>

using chip::Callback::Callback;
using chip::Callback::Cancelable;
using namespace chip::app::Clusters;
using chip::Messaging::ExchangeManager;
using chip::SessionHandle;

// NOLINTBEGIN(clang-analyzer-cplusplus.NewDeleteLeaks): Linter is unable to locate the delete on these objects.
@implementation MTRBaseClusterIdentify

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = endpoint;
    }
    return self;
}

- (void)identifyWithParams:(MTRIdentifyClusterIdentifyParams *)params completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            Identify::Commands::Identify::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.identifyTime = params.identifyTime.unsignedShortValue;

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::IdentifyCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)triggerEffectWithParams:(MTRIdentifyClusterTriggerEffectParams *)params
              completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            Identify::Commands::TriggerEffect::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.effectIdentifier = static_cast<std::remove_reference_t<decltype(request.effectIdentifier)>>(
                params.effectIdentifier.unsignedCharValue);
            request.effectVariant
                = static_cast<std::remove_reference_t<decltype(request.effectVariant)>>(params.effectVariant.unsignedCharValue);

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::IdentifyCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)readAttributeIdentifyTimeWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Identify::Attributes::IdentifyTime::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::IdentifyCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeIdentifyTimeWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeIdentifyTimeWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeIdentifyTimeWithValue:(NSNumber * _Nonnull)value
                                     params:(MTRWriteParams * _Nullable)params
                          completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = Identify::Attributes::IdentifyTime::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::IdentifyCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeIdentifyTimeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Identify::Attributes::IdentifyTime::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::IdentifyCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeIdentifyTimeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Identify::Attributes::IdentifyTime::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeIdentifyTypeWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Identify::Attributes::IdentifyType::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::IdentifyCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeIdentifyTypeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Identify::Attributes::IdentifyType::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::IdentifyCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeIdentifyTypeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Identify::Attributes::IdentifyType::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRIdentifyGeneratedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Identify::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<IdentifyGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::IdentifyCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRIdentifyGeneratedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Identify::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<IdentifyGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::IdentifyCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRIdentifyGeneratedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRIdentifyGeneratedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Identify::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<IdentifyGeneratedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRIdentifyAcceptedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Identify::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<IdentifyAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::IdentifyCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRIdentifyAcceptedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Identify::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<IdentifyAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::IdentifyCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRIdentifyAcceptedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRIdentifyAcceptedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Identify::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<IdentifyAcceptedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRIdentifyAttributeListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Identify::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<IdentifyAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::IdentifyCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRIdentifyAttributeListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Identify::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<IdentifyAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::IdentifyCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRIdentifyAttributeListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRIdentifyAttributeListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Identify::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<IdentifyAttributeListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Identify::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::IdentifyCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Identify::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::IdentifyCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Identify::Attributes::FeatureMap::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Identify::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::IdentifyCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Identify::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::IdentifyCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Identify::Attributes::ClusterRevision::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

@end

@implementation MTRBaseClusterGroups

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = endpoint;
    }
    return self;
}

- (void)addGroupWithParams:(MTRGroupsClusterAddGroupParams *)params
         completionHandler:
             (void (^)(MTRGroupsClusterAddGroupResponseParams * _Nullable data, NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRGroupsClusterAddGroupResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            Groups::Commands::AddGroup::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.groupId = params.groupId.unsignedShortValue;
            request.groupName = [self asCharSpan:params.groupName];

            auto successFn = Callback<GroupsClusterAddGroupResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::GroupsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)viewGroupWithParams:(MTRGroupsClusterViewGroupParams *)params
          completionHandler:
              (void (^)(MTRGroupsClusterViewGroupResponseParams * _Nullable data, NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRGroupsClusterViewGroupResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            Groups::Commands::ViewGroup::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.groupId = params.groupId.unsignedShortValue;

            auto successFn = Callback<GroupsClusterViewGroupResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::GroupsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)getGroupMembershipWithParams:(MTRGroupsClusterGetGroupMembershipParams *)params
                   completionHandler:(void (^)(MTRGroupsClusterGetGroupMembershipResponseParams * _Nullable data,
                                         NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRGroupsClusterGetGroupMembershipResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            Groups::Commands::GetGroupMembership::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            {
                using ListType_0 = std::remove_reference_t<decltype(request.groupList)>;
                using ListMemberType_0 = ListMemberTypeGetter<ListType_0>::Type;
                if (params.groupList.count != 0) {
                    auto * listHolder_0 = new ListHolder<ListMemberType_0>(params.groupList.count);
                    if (listHolder_0 == nullptr || listHolder_0->mList == nullptr) {
                        return CHIP_ERROR_INVALID_ARGUMENT;
                    }
                    listFreer.add(listHolder_0);
                    for (size_t i_0 = 0; i_0 < params.groupList.count; ++i_0) {
                        if (![params.groupList[i_0] isKindOfClass:[NSNumber class]]) {
                            // Wrong kind of value.
                            return CHIP_ERROR_INVALID_ARGUMENT;
                        }
                        auto element_0 = (NSNumber *) params.groupList[i_0];
                        listHolder_0->mList[i_0] = element_0.unsignedShortValue;
                    }
                    request.groupList = ListType_0(listHolder_0->mList, params.groupList.count);
                } else {
                    request.groupList = ListType_0();
                }
            }

            auto successFn = Callback<GroupsClusterGetGroupMembershipResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::GroupsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)removeGroupWithParams:(MTRGroupsClusterRemoveGroupParams *)params
            completionHandler:
                (void (^)(MTRGroupsClusterRemoveGroupResponseParams * _Nullable data, NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRGroupsClusterRemoveGroupResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            Groups::Commands::RemoveGroup::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.groupId = params.groupId.unsignedShortValue;

            auto successFn = Callback<GroupsClusterRemoveGroupResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::GroupsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)removeAllGroupsWithCompletionHandler:(StatusCompletion)completionHandler
{
    [self removeAllGroupsWithParams:nil completionHandler:completionHandler];
}
- (void)removeAllGroupsWithParams:(MTRGroupsClusterRemoveAllGroupsParams * _Nullable)params
                completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            Groups::Commands::RemoveAllGroups::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::GroupsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)addGroupIfIdentifyingWithParams:(MTRGroupsClusterAddGroupIfIdentifyingParams *)params
                      completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            Groups::Commands::AddGroupIfIdentifying::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.groupId = params.groupId.unsignedShortValue;
            request.groupName = [self asCharSpan:params.groupName];

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::GroupsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)readAttributeNameSupportWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Groups::Attributes::NameSupport::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::GroupsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeNameSupportWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Groups::Attributes::NameSupport::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::GroupsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeNameSupportWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Groups::Attributes::NameSupport::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRGroupsGeneratedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Groups::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<GroupsGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::GroupsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRGroupsGeneratedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Groups::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<GroupsGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::GroupsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRGroupsGeneratedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRGroupsGeneratedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Groups::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<GroupsGeneratedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRGroupsAcceptedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Groups::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<GroupsAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::GroupsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRGroupsAcceptedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Groups::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<GroupsAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::GroupsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRGroupsAcceptedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRGroupsAcceptedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Groups::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<GroupsAcceptedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRGroupsAttributeListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Groups::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<GroupsAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::GroupsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRGroupsAttributeListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Groups::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<GroupsAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::GroupsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRGroupsAttributeListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRGroupsAttributeListListAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Groups::Attributes::AttributeList::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<GroupsAttributeListListAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Groups::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::GroupsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Groups::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::GroupsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Groups::Attributes::FeatureMap::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Groups::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::GroupsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Groups::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::GroupsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Groups::Attributes::ClusterRevision::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

@end

@implementation MTRBaseClusterScenes

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = endpoint;
    }
    return self;
}

- (void)addSceneWithParams:(MTRScenesClusterAddSceneParams *)params
         completionHandler:
             (void (^)(MTRScenesClusterAddSceneResponseParams * _Nullable data, NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRScenesClusterAddSceneResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            Scenes::Commands::AddScene::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.groupId = params.groupId.unsignedShortValue;
            request.sceneId = params.sceneId.unsignedCharValue;
            request.transitionTime = params.transitionTime.unsignedShortValue;
            request.sceneName = [self asCharSpan:params.sceneName];
            {
                using ListType_0 = std::remove_reference_t<decltype(request.extensionFieldSets)>;
                using ListMemberType_0 = ListMemberTypeGetter<ListType_0>::Type;
                if (params.extensionFieldSets.count != 0) {
                    auto * listHolder_0 = new ListHolder<ListMemberType_0>(params.extensionFieldSets.count);
                    if (listHolder_0 == nullptr || listHolder_0->mList == nullptr) {
                        return CHIP_ERROR_INVALID_ARGUMENT;
                    }
                    listFreer.add(listHolder_0);
                    for (size_t i_0 = 0; i_0 < params.extensionFieldSets.count; ++i_0) {
                        if (![params.extensionFieldSets[i_0] isKindOfClass:[MTRScenesClusterExtensionFieldSet class]]) {
                            // Wrong kind of value.
                            return CHIP_ERROR_INVALID_ARGUMENT;
                        }
                        auto element_0 = (MTRScenesClusterExtensionFieldSet *) params.extensionFieldSets[i_0];
                        listHolder_0->mList[i_0].clusterId = element_0.clusterId.unsignedIntValue;
                        {
                            using ListType_2 = std::remove_reference_t<decltype(listHolder_0->mList[i_0].attributeValueList)>;
                            using ListMemberType_2 = ListMemberTypeGetter<ListType_2>::Type;
                            if (element_0.attributeValueList.count != 0) {
                                auto * listHolder_2 = new ListHolder<ListMemberType_2>(element_0.attributeValueList.count);
                                if (listHolder_2 == nullptr || listHolder_2->mList == nullptr) {
                                    return CHIP_ERROR_INVALID_ARGUMENT;
                                }
                                listFreer.add(listHolder_2);
                                for (size_t i_2 = 0; i_2 < element_0.attributeValueList.count; ++i_2) {
                                    if (![element_0.attributeValueList[i_2]
                                            isKindOfClass:[MTRScenesClusterAttributeValuePair class]]) {
                                        // Wrong kind of value.
                                        return CHIP_ERROR_INVALID_ARGUMENT;
                                    }
                                    auto element_2 = (MTRScenesClusterAttributeValuePair *) element_0.attributeValueList[i_2];
                                    if (element_2.attributeId != nil) {
                                        auto & definedValue_4 = listHolder_2->mList[i_2].attributeId.Emplace();
                                        definedValue_4 = element_2.attributeId.unsignedIntValue;
                                    }
                                    {
                                        using ListType_4
                                            = std::remove_reference_t<decltype(listHolder_2->mList[i_2].attributeValue)>;
                                        using ListMemberType_4 = ListMemberTypeGetter<ListType_4>::Type;
                                        if (element_2.attributeValue.count != 0) {
                                            auto * listHolder_4 = new ListHolder<ListMemberType_4>(element_2.attributeValue.count);
                                            if (listHolder_4 == nullptr || listHolder_4->mList == nullptr) {
                                                return CHIP_ERROR_INVALID_ARGUMENT;
                                            }
                                            listFreer.add(listHolder_4);
                                            for (size_t i_4 = 0; i_4 < element_2.attributeValue.count; ++i_4) {
                                                if (![element_2.attributeValue[i_4] isKindOfClass:[NSNumber class]]) {
                                                    // Wrong kind of value.
                                                    return CHIP_ERROR_INVALID_ARGUMENT;
                                                }
                                                auto element_4 = (NSNumber *) element_2.attributeValue[i_4];
                                                listHolder_4->mList[i_4] = element_4.unsignedCharValue;
                                            }
                                            listHolder_2->mList[i_2].attributeValue
                                                = ListType_4(listHolder_4->mList, element_2.attributeValue.count);
                                        } else {
                                            listHolder_2->mList[i_2].attributeValue = ListType_4();
                                        }
                                    }
                                }
                                listHolder_0->mList[i_0].attributeValueList
                                    = ListType_2(listHolder_2->mList, element_0.attributeValueList.count);
                            } else {
                                listHolder_0->mList[i_0].attributeValueList = ListType_2();
                            }
                        }
                    }
                    request.extensionFieldSets = ListType_0(listHolder_0->mList, params.extensionFieldSets.count);
                } else {
                    request.extensionFieldSets = ListType_0();
                }
            }

            auto successFn = Callback<ScenesClusterAddSceneResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ScenesCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)viewSceneWithParams:(MTRScenesClusterViewSceneParams *)params
          completionHandler:
              (void (^)(MTRScenesClusterViewSceneResponseParams * _Nullable data, NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRScenesClusterViewSceneResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            Scenes::Commands::ViewScene::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.groupId = params.groupId.unsignedShortValue;
            request.sceneId = params.sceneId.unsignedCharValue;

            auto successFn = Callback<ScenesClusterViewSceneResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ScenesCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)removeSceneWithParams:(MTRScenesClusterRemoveSceneParams *)params
            completionHandler:
                (void (^)(MTRScenesClusterRemoveSceneResponseParams * _Nullable data, NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRScenesClusterRemoveSceneResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            Scenes::Commands::RemoveScene::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.groupId = params.groupId.unsignedShortValue;
            request.sceneId = params.sceneId.unsignedCharValue;

            auto successFn = Callback<ScenesClusterRemoveSceneResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ScenesCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)removeAllScenesWithParams:(MTRScenesClusterRemoveAllScenesParams *)params
                completionHandler:(void (^)(MTRScenesClusterRemoveAllScenesResponseParams * _Nullable data,
                                      NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRScenesClusterRemoveAllScenesResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            Scenes::Commands::RemoveAllScenes::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.groupId = params.groupId.unsignedShortValue;

            auto successFn = Callback<ScenesClusterRemoveAllScenesResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ScenesCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)storeSceneWithParams:(MTRScenesClusterStoreSceneParams *)params
           completionHandler:
               (void (^)(MTRScenesClusterStoreSceneResponseParams * _Nullable data, NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRScenesClusterStoreSceneResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            Scenes::Commands::StoreScene::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.groupId = params.groupId.unsignedShortValue;
            request.sceneId = params.sceneId.unsignedCharValue;

            auto successFn = Callback<ScenesClusterStoreSceneResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ScenesCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)recallSceneWithParams:(MTRScenesClusterRecallSceneParams *)params completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            Scenes::Commands::RecallScene::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.groupId = params.groupId.unsignedShortValue;
            request.sceneId = params.sceneId.unsignedCharValue;
            if (params.transitionTime != nil) {
                auto & definedValue_0 = request.transitionTime.Emplace();
                if (params.transitionTime == nil) {
                    definedValue_0.SetNull();
                } else {
                    auto & nonNullValue_1 = definedValue_0.SetNonNull();
                    nonNullValue_1 = params.transitionTime.unsignedShortValue;
                }
            }

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ScenesCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)getSceneMembershipWithParams:(MTRScenesClusterGetSceneMembershipParams *)params
                   completionHandler:(void (^)(MTRScenesClusterGetSceneMembershipResponseParams * _Nullable data,
                                         NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRScenesClusterGetSceneMembershipResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            Scenes::Commands::GetSceneMembership::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.groupId = params.groupId.unsignedShortValue;

            auto successFn = Callback<ScenesClusterGetSceneMembershipResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ScenesCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)enhancedAddSceneWithParams:(MTRScenesClusterEnhancedAddSceneParams *)params
                 completionHandler:(void (^)(MTRScenesClusterEnhancedAddSceneResponseParams * _Nullable data,
                                       NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRScenesClusterEnhancedAddSceneResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            Scenes::Commands::EnhancedAddScene::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.groupId = params.groupId.unsignedShortValue;
            request.sceneId = params.sceneId.unsignedCharValue;
            request.transitionTime = params.transitionTime.unsignedShortValue;
            request.sceneName = [self asCharSpan:params.sceneName];
            {
                using ListType_0 = std::remove_reference_t<decltype(request.extensionFieldSets)>;
                using ListMemberType_0 = ListMemberTypeGetter<ListType_0>::Type;
                if (params.extensionFieldSets.count != 0) {
                    auto * listHolder_0 = new ListHolder<ListMemberType_0>(params.extensionFieldSets.count);
                    if (listHolder_0 == nullptr || listHolder_0->mList == nullptr) {
                        return CHIP_ERROR_INVALID_ARGUMENT;
                    }
                    listFreer.add(listHolder_0);
                    for (size_t i_0 = 0; i_0 < params.extensionFieldSets.count; ++i_0) {
                        if (![params.extensionFieldSets[i_0] isKindOfClass:[MTRScenesClusterExtensionFieldSet class]]) {
                            // Wrong kind of value.
                            return CHIP_ERROR_INVALID_ARGUMENT;
                        }
                        auto element_0 = (MTRScenesClusterExtensionFieldSet *) params.extensionFieldSets[i_0];
                        listHolder_0->mList[i_0].clusterId = element_0.clusterId.unsignedIntValue;
                        {
                            using ListType_2 = std::remove_reference_t<decltype(listHolder_0->mList[i_0].attributeValueList)>;
                            using ListMemberType_2 = ListMemberTypeGetter<ListType_2>::Type;
                            if (element_0.attributeValueList.count != 0) {
                                auto * listHolder_2 = new ListHolder<ListMemberType_2>(element_0.attributeValueList.count);
                                if (listHolder_2 == nullptr || listHolder_2->mList == nullptr) {
                                    return CHIP_ERROR_INVALID_ARGUMENT;
                                }
                                listFreer.add(listHolder_2);
                                for (size_t i_2 = 0; i_2 < element_0.attributeValueList.count; ++i_2) {
                                    if (![element_0.attributeValueList[i_2]
                                            isKindOfClass:[MTRScenesClusterAttributeValuePair class]]) {
                                        // Wrong kind of value.
                                        return CHIP_ERROR_INVALID_ARGUMENT;
                                    }
                                    auto element_2 = (MTRScenesClusterAttributeValuePair *) element_0.attributeValueList[i_2];
                                    if (element_2.attributeId != nil) {
                                        auto & definedValue_4 = listHolder_2->mList[i_2].attributeId.Emplace();
                                        definedValue_4 = element_2.attributeId.unsignedIntValue;
                                    }
                                    {
                                        using ListType_4
                                            = std::remove_reference_t<decltype(listHolder_2->mList[i_2].attributeValue)>;
                                        using ListMemberType_4 = ListMemberTypeGetter<ListType_4>::Type;
                                        if (element_2.attributeValue.count != 0) {
                                            auto * listHolder_4 = new ListHolder<ListMemberType_4>(element_2.attributeValue.count);
                                            if (listHolder_4 == nullptr || listHolder_4->mList == nullptr) {
                                                return CHIP_ERROR_INVALID_ARGUMENT;
                                            }
                                            listFreer.add(listHolder_4);
                                            for (size_t i_4 = 0; i_4 < element_2.attributeValue.count; ++i_4) {
                                                if (![element_2.attributeValue[i_4] isKindOfClass:[NSNumber class]]) {
                                                    // Wrong kind of value.
                                                    return CHIP_ERROR_INVALID_ARGUMENT;
                                                }
                                                auto element_4 = (NSNumber *) element_2.attributeValue[i_4];
                                                listHolder_4->mList[i_4] = element_4.unsignedCharValue;
                                            }
                                            listHolder_2->mList[i_2].attributeValue
                                                = ListType_4(listHolder_4->mList, element_2.attributeValue.count);
                                        } else {
                                            listHolder_2->mList[i_2].attributeValue = ListType_4();
                                        }
                                    }
                                }
                                listHolder_0->mList[i_0].attributeValueList
                                    = ListType_2(listHolder_2->mList, element_0.attributeValueList.count);
                            } else {
                                listHolder_0->mList[i_0].attributeValueList = ListType_2();
                            }
                        }
                    }
                    request.extensionFieldSets = ListType_0(listHolder_0->mList, params.extensionFieldSets.count);
                } else {
                    request.extensionFieldSets = ListType_0();
                }
            }

            auto successFn = Callback<ScenesClusterEnhancedAddSceneResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ScenesCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)enhancedViewSceneWithParams:(MTRScenesClusterEnhancedViewSceneParams *)params
                  completionHandler:(void (^)(MTRScenesClusterEnhancedViewSceneResponseParams * _Nullable data,
                                        NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRScenesClusterEnhancedViewSceneResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            Scenes::Commands::EnhancedViewScene::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.groupId = params.groupId.unsignedShortValue;
            request.sceneId = params.sceneId.unsignedCharValue;

            auto successFn = Callback<ScenesClusterEnhancedViewSceneResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ScenesCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)copySceneWithParams:(MTRScenesClusterCopySceneParams *)params
          completionHandler:
              (void (^)(MTRScenesClusterCopySceneResponseParams * _Nullable data, NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRScenesClusterCopySceneResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            Scenes::Commands::CopyScene::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.mode = static_cast<std::remove_reference_t<decltype(request.mode)>>(params.mode.unsignedCharValue);
            request.groupIdFrom = params.groupIdFrom.unsignedShortValue;
            request.sceneIdFrom = params.sceneIdFrom.unsignedCharValue;
            request.groupIdTo = params.groupIdTo.unsignedShortValue;
            request.sceneIdTo = params.sceneIdTo.unsignedCharValue;

            auto successFn = Callback<ScenesClusterCopySceneResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ScenesCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)readAttributeSceneCountWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Scenes::Attributes::SceneCount::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ScenesCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeSceneCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Scenes::Attributes::SceneCount::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ScenesCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeSceneCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Scenes::Attributes::SceneCount::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeCurrentSceneWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Scenes::Attributes::CurrentScene::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ScenesCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeCurrentSceneWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Scenes::Attributes::CurrentScene::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ScenesCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeCurrentSceneWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Scenes::Attributes::CurrentScene::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeCurrentGroupWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Scenes::Attributes::CurrentGroup::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ScenesCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeCurrentGroupWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Scenes::Attributes::CurrentGroup::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ScenesCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeCurrentGroupWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Scenes::Attributes::CurrentGroup::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeSceneValidWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBooleanAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Scenes::Attributes::SceneValid::TypeInfo;
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ScenesCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeSceneValidWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRBooleanAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Scenes::Attributes::SceneValid::TypeInfo;
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ScenesCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRBooleanAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeSceneValidWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBooleanAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Scenes::Attributes::SceneValid::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeNameSupportWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Scenes::Attributes::NameSupport::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ScenesCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeNameSupportWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Scenes::Attributes::NameSupport::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ScenesCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeNameSupportWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Scenes::Attributes::NameSupport::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeLastConfiguredByWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    new MTRNullableInt64uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Scenes::Attributes::LastConfiguredBy::TypeInfo;
            auto successFn = Callback<NullableInt64uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ScenesCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeLastConfiguredByWithMinInterval:(NSNumber * _Nonnull)minInterval
                                              maxInterval:(NSNumber * _Nonnull)maxInterval
                                                   params:(MTRSubscribeParams * _Nullable)params
                                  subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                            reportHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt64uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Scenes::Attributes::LastConfiguredBy::TypeInfo;
            auto successFn = Callback<NullableInt64uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ScenesCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt64uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeLastConfiguredByWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt64uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Scenes::Attributes::LastConfiguredBy::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt64uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRScenesGeneratedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Scenes::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<ScenesGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ScenesCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRScenesGeneratedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Scenes::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<ScenesGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ScenesCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRScenesGeneratedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRScenesGeneratedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Scenes::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<ScenesGeneratedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRScenesAcceptedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Scenes::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<ScenesAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ScenesCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRScenesAcceptedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Scenes::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<ScenesAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ScenesCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRScenesAcceptedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRScenesAcceptedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Scenes::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<ScenesAcceptedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRScenesAttributeListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Scenes::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<ScenesAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ScenesCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRScenesAttributeListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Scenes::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<ScenesAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ScenesCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRScenesAttributeListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRScenesAttributeListListAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Scenes::Attributes::AttributeList::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<ScenesAttributeListListAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Scenes::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ScenesCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Scenes::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ScenesCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Scenes::Attributes::FeatureMap::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Scenes::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ScenesCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Scenes::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ScenesCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Scenes::Attributes::ClusterRevision::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

@end

@implementation MTRBaseClusterOnOff

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = endpoint;
    }
    return self;
}

- (void)offWithCompletionHandler:(StatusCompletion)completionHandler
{
    [self offWithParams:nil completionHandler:completionHandler];
}
- (void)offWithParams:(MTROnOffClusterOffParams * _Nullable)params completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            OnOff::Commands::Off::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OnOffCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)onWithCompletionHandler:(StatusCompletion)completionHandler
{
    [self onWithParams:nil completionHandler:completionHandler];
}
- (void)onWithParams:(MTROnOffClusterOnParams * _Nullable)params completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            OnOff::Commands::On::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OnOffCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)toggleWithCompletionHandler:(StatusCompletion)completionHandler
{
    [self toggleWithParams:nil completionHandler:completionHandler];
}
- (void)toggleWithParams:(MTROnOffClusterToggleParams * _Nullable)params completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            OnOff::Commands::Toggle::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OnOffCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)offWithEffectWithParams:(MTROnOffClusterOffWithEffectParams *)params completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            OnOff::Commands::OffWithEffect::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.effectId = static_cast<std::remove_reference_t<decltype(request.effectId)>>(params.effectId.unsignedCharValue);
            request.effectVariant
                = static_cast<std::remove_reference_t<decltype(request.effectVariant)>>(params.effectVariant.unsignedCharValue);

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OnOffCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)onWithRecallGlobalSceneWithCompletionHandler:(StatusCompletion)completionHandler
{
    [self onWithRecallGlobalSceneWithParams:nil completionHandler:completionHandler];
}
- (void)onWithRecallGlobalSceneWithParams:(MTROnOffClusterOnWithRecallGlobalSceneParams * _Nullable)params
                        completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            OnOff::Commands::OnWithRecallGlobalScene::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OnOffCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)onWithTimedOffWithParams:(MTROnOffClusterOnWithTimedOffParams *)params completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            OnOff::Commands::OnWithTimedOff::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.onOffControl
                = static_cast<std::remove_reference_t<decltype(request.onOffControl)>>(params.onOffControl.unsignedCharValue);
            request.onTime = params.onTime.unsignedShortValue;
            request.offWaitTime = params.offWaitTime.unsignedShortValue;

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OnOffCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)readAttributeOnOffWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBooleanAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = OnOff::Attributes::OnOff::TypeInfo;
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OnOffCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeOnOffWithMinInterval:(NSNumber * _Nonnull)minInterval
                                   maxInterval:(NSNumber * _Nonnull)maxInterval
                                        params:(MTRSubscribeParams * _Nullable)params
                       subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRBooleanAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = OnOff::Attributes::OnOff::TypeInfo;
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::OnOffCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRBooleanAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeOnOffWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                    endpoint:(NSNumber *)endpoint
                                       queue:(dispatch_queue_t)queue
                           completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBooleanAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = OnOff::Attributes::OnOff::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeGlobalSceneControlWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                 NSError * _Nullable error))completionHandler
{
    new MTRBooleanAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = OnOff::Attributes::GlobalSceneControl::TypeInfo;
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OnOffCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeGlobalSceneControlWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                maxInterval:(NSNumber * _Nonnull)maxInterval
                                                     params:(MTRSubscribeParams * _Nullable)params
                                    subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                              reportHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRBooleanAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = OnOff::Attributes::GlobalSceneControl::TypeInfo;
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::OnOffCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRBooleanAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeGlobalSceneControlWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                        completionHandler:
                                            (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBooleanAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = OnOff::Attributes::GlobalSceneControl::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeOnTimeWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = OnOff::Attributes::OnTime::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OnOffCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeOnTimeWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeOnTimeWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeOnTimeWithValue:(NSNumber * _Nonnull)value
                               params:(MTRWriteParams * _Nullable)params
                    completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = OnOff::Attributes::OnTime::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::OnOffCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeOnTimeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                         params:(MTRSubscribeParams * _Nullable)params
                        subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = OnOff::Attributes::OnTime::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::OnOffCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeOnTimeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                     endpoint:(NSNumber *)endpoint
                                        queue:(dispatch_queue_t)queue
                            completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = OnOff::Attributes::OnTime::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeOffWaitTimeWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = OnOff::Attributes::OffWaitTime::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OnOffCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeOffWaitTimeWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeOffWaitTimeWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeOffWaitTimeWithValue:(NSNumber * _Nonnull)value
                                    params:(MTRWriteParams * _Nullable)params
                         completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = OnOff::Attributes::OffWaitTime::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::OnOffCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeOffWaitTimeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = OnOff::Attributes::OffWaitTime::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::OnOffCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeOffWaitTimeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = OnOff::Attributes::OffWaitTime::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeStartUpOnOffWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableOnOffClusterOnOffStartUpOnOffAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = OnOff::Attributes::StartUpOnOff::TypeInfo;
            auto successFn = Callback<NullableOnOffClusterOnOffStartUpOnOffAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OnOffCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeStartUpOnOffWithValue:(NSNumber * _Nullable)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeStartUpOnOffWithValue:(NSNumber * _Nullable) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeStartUpOnOffWithValue:(NSNumber * _Nullable)value
                                     params:(MTRWriteParams * _Nullable)params
                          completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = OnOff::Attributes::StartUpOnOff::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = static_cast<std::remove_reference_t<decltype(nonNullValue_0)>>(value.unsignedCharValue);
            }
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::OnOffCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeStartUpOnOffWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableOnOffClusterOnOffStartUpOnOffAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = OnOff::Attributes::StartUpOnOff::TypeInfo;
            auto successFn = Callback<NullableOnOffClusterOnOffStartUpOnOffAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::OnOffCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableOnOffClusterOnOffStartUpOnOffAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeStartUpOnOffWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableOnOffClusterOnOffStartUpOnOffAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OnOff::Attributes::StartUpOnOff::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<NullableOnOffClusterOnOffStartUpOnOffAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTROnOffGeneratedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = OnOff::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<OnOffGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OnOffCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTROnOffGeneratedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = OnOff::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<OnOffGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::OnOffCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTROnOffGeneratedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTROnOffGeneratedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OnOff::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<OnOffGeneratedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTROnOffAcceptedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = OnOff::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<OnOffAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OnOffCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTROnOffAcceptedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = OnOff::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<OnOffAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::OnOffCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTROnOffAcceptedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTROnOffAcceptedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OnOff::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<OnOffAcceptedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTROnOffAttributeListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = OnOff::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<OnOffAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OnOffCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTROnOffAttributeListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = OnOff::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<OnOffAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::OnOffCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTROnOffAttributeListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTROnOffAttributeListListAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = OnOff::Attributes::AttributeList::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<OnOffAttributeListListAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = OnOff::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OnOffCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = OnOff::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::OnOffCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = OnOff::Attributes::FeatureMap::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = OnOff::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OnOffCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = OnOff::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::OnOffCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = OnOff::Attributes::ClusterRevision::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

@end

@implementation MTRBaseClusterOnOffSwitchConfiguration

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = endpoint;
    }
    return self;
}

- (void)readAttributeSwitchTypeWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = OnOffSwitchConfiguration::Attributes::SwitchType::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OnOffSwitchConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeSwitchTypeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = OnOffSwitchConfiguration::Attributes::SwitchType::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::OnOffSwitchConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeSwitchTypeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = OnOffSwitchConfiguration::Attributes::SwitchType::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeSwitchActionsWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = OnOffSwitchConfiguration::Attributes::SwitchActions::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OnOffSwitchConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeSwitchActionsWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeSwitchActionsWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeSwitchActionsWithValue:(NSNumber * _Nonnull)value
                                      params:(MTRWriteParams * _Nullable)params
                           completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = OnOffSwitchConfiguration::Attributes::SwitchActions::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedCharValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::OnOffSwitchConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeSwitchActionsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = OnOffSwitchConfiguration::Attributes::SwitchActions::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::OnOffSwitchConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeSwitchActionsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = OnOffSwitchConfiguration::Attributes::SwitchActions::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTROnOffSwitchConfigurationGeneratedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device,
        completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = OnOffSwitchConfiguration::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<OnOffSwitchConfigurationGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OnOffSwitchConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTROnOffSwitchConfigurationGeneratedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = OnOffSwitchConfiguration::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<OnOffSwitchConfigurationGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::OnOffSwitchConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTROnOffSwitchConfigurationGeneratedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished,
                nil, params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTROnOffSwitchConfigurationGeneratedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OnOffSwitchConfiguration::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn
                    = Callback<OnOffSwitchConfigurationGeneratedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTROnOffSwitchConfigurationAcceptedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device,
        completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = OnOffSwitchConfiguration::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<OnOffSwitchConfigurationAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OnOffSwitchConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTROnOffSwitchConfigurationAcceptedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = OnOffSwitchConfiguration::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<OnOffSwitchConfigurationAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::OnOffSwitchConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTROnOffSwitchConfigurationAcceptedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished,
                nil, params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTROnOffSwitchConfigurationAcceptedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OnOffSwitchConfiguration::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn
                    = Callback<OnOffSwitchConfigurationAcceptedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTROnOffSwitchConfigurationAttributeListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = OnOffSwitchConfiguration::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<OnOffSwitchConfigurationAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OnOffSwitchConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTROnOffSwitchConfigurationAttributeListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = OnOffSwitchConfiguration::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<OnOffSwitchConfigurationAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::OnOffSwitchConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTROnOffSwitchConfigurationAttributeListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTROnOffSwitchConfigurationAttributeListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OnOffSwitchConfiguration::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<OnOffSwitchConfigurationAttributeListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = OnOffSwitchConfiguration::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OnOffSwitchConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = OnOffSwitchConfiguration::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::OnOffSwitchConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = OnOffSwitchConfiguration::Attributes::FeatureMap::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = OnOffSwitchConfiguration::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OnOffSwitchConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = OnOffSwitchConfiguration::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::OnOffSwitchConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = OnOffSwitchConfiguration::Attributes::ClusterRevision::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

@end

@implementation MTRBaseClusterLevelControl

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = endpoint;
    }
    return self;
}

- (void)moveToLevelWithParams:(MTRLevelControlClusterMoveToLevelParams *)params
            completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            LevelControl::Commands::MoveToLevel::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.level = params.level.unsignedCharValue;
            if (params.transitionTime == nil) {
                request.transitionTime.SetNull();
            } else {
                auto & nonNullValue_0 = request.transitionTime.SetNonNull();
                nonNullValue_0 = params.transitionTime.unsignedShortValue;
            }
            request.optionsMask = params.optionsMask.unsignedCharValue;
            request.optionsOverride = params.optionsOverride.unsignedCharValue;

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::LevelControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)moveWithParams:(MTRLevelControlClusterMoveParams *)params completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            LevelControl::Commands::Move::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.moveMode = static_cast<std::remove_reference_t<decltype(request.moveMode)>>(params.moveMode.unsignedCharValue);
            if (params.rate == nil) {
                request.rate.SetNull();
            } else {
                auto & nonNullValue_0 = request.rate.SetNonNull();
                nonNullValue_0 = params.rate.unsignedCharValue;
            }
            request.optionsMask = params.optionsMask.unsignedCharValue;
            request.optionsOverride = params.optionsOverride.unsignedCharValue;

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::LevelControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)stepWithParams:(MTRLevelControlClusterStepParams *)params completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            LevelControl::Commands::Step::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.stepMode = static_cast<std::remove_reference_t<decltype(request.stepMode)>>(params.stepMode.unsignedCharValue);
            request.stepSize = params.stepSize.unsignedCharValue;
            if (params.transitionTime == nil) {
                request.transitionTime.SetNull();
            } else {
                auto & nonNullValue_0 = request.transitionTime.SetNonNull();
                nonNullValue_0 = params.transitionTime.unsignedShortValue;
            }
            request.optionsMask = params.optionsMask.unsignedCharValue;
            request.optionsOverride = params.optionsOverride.unsignedCharValue;

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::LevelControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)stopWithParams:(MTRLevelControlClusterStopParams *)params completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            LevelControl::Commands::Stop::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.optionsMask = params.optionsMask.unsignedCharValue;
            request.optionsOverride = params.optionsOverride.unsignedCharValue;

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::LevelControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)moveToLevelWithOnOffWithParams:(MTRLevelControlClusterMoveToLevelWithOnOffParams *)params
                     completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            LevelControl::Commands::MoveToLevelWithOnOff::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.level = params.level.unsignedCharValue;
            if (params.transitionTime == nil) {
                request.transitionTime.SetNull();
            } else {
                auto & nonNullValue_0 = request.transitionTime.SetNonNull();
                nonNullValue_0 = params.transitionTime.unsignedShortValue;
            }
            request.optionsMask = params.optionsMask.unsignedCharValue;
            request.optionsOverride = params.optionsOverride.unsignedCharValue;

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::LevelControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)moveWithOnOffWithParams:(MTRLevelControlClusterMoveWithOnOffParams *)params
              completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            LevelControl::Commands::MoveWithOnOff::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.moveMode = static_cast<std::remove_reference_t<decltype(request.moveMode)>>(params.moveMode.unsignedCharValue);
            if (params.rate == nil) {
                request.rate.SetNull();
            } else {
                auto & nonNullValue_0 = request.rate.SetNonNull();
                nonNullValue_0 = params.rate.unsignedCharValue;
            }
            request.optionsMask = params.optionsMask.unsignedCharValue;
            request.optionsOverride = params.optionsOverride.unsignedCharValue;

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::LevelControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)stepWithOnOffWithParams:(MTRLevelControlClusterStepWithOnOffParams *)params
              completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            LevelControl::Commands::StepWithOnOff::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.stepMode = static_cast<std::remove_reference_t<decltype(request.stepMode)>>(params.stepMode.unsignedCharValue);
            request.stepSize = params.stepSize.unsignedCharValue;
            if (params.transitionTime == nil) {
                request.transitionTime.SetNull();
            } else {
                auto & nonNullValue_0 = request.transitionTime.SetNonNull();
                nonNullValue_0 = params.transitionTime.unsignedShortValue;
            }
            request.optionsMask = params.optionsMask.unsignedCharValue;
            request.optionsOverride = params.optionsOverride.unsignedCharValue;

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::LevelControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)stopWithOnOffWithParams:(MTRLevelControlClusterStopWithOnOffParams *)params
              completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            LevelControl::Commands::StopWithOnOff::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.optionsMask = params.optionsMask.unsignedCharValue;
            request.optionsOverride = params.optionsOverride.unsignedCharValue;

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::LevelControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)moveToClosestFrequencyWithParams:(MTRLevelControlClusterMoveToClosestFrequencyParams *)params
                       completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            LevelControl::Commands::MoveToClosestFrequency::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.frequency = params.frequency.unsignedShortValue;

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::LevelControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)readAttributeCurrentLevelWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = LevelControl::Attributes::CurrentLevel::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::LevelControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeCurrentLevelWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = LevelControl::Attributes::CurrentLevel::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::LevelControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeCurrentLevelWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = LevelControl::Attributes::CurrentLevel::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeRemainingTimeWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = LevelControl::Attributes::RemainingTime::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::LevelControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeRemainingTimeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = LevelControl::Attributes::RemainingTime::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::LevelControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeRemainingTimeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = LevelControl::Attributes::RemainingTime::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeMinLevelWithCompletionHandler:(void (^)(
                                                       NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = LevelControl::Attributes::MinLevel::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::LevelControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeMinLevelWithMinInterval:(NSNumber * _Nonnull)minInterval
                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                           params:(MTRSubscribeParams * _Nullable)params
                          subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = LevelControl::Attributes::MinLevel::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::LevelControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeMinLevelWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                       endpoint:(NSNumber *)endpoint
                                          queue:(dispatch_queue_t)queue
                              completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = LevelControl::Attributes::MinLevel::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeMaxLevelWithCompletionHandler:(void (^)(
                                                       NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = LevelControl::Attributes::MaxLevel::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::LevelControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeMaxLevelWithMinInterval:(NSNumber * _Nonnull)minInterval
                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                           params:(MTRSubscribeParams * _Nullable)params
                          subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = LevelControl::Attributes::MaxLevel::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::LevelControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeMaxLevelWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                       endpoint:(NSNumber *)endpoint
                                          queue:(dispatch_queue_t)queue
                              completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = LevelControl::Attributes::MaxLevel::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeCurrentFrequencyWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = LevelControl::Attributes::CurrentFrequency::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::LevelControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeCurrentFrequencyWithMinInterval:(NSNumber * _Nonnull)minInterval
                                              maxInterval:(NSNumber * _Nonnull)maxInterval
                                                   params:(MTRSubscribeParams * _Nullable)params
                                  subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                            reportHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = LevelControl::Attributes::CurrentFrequency::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::LevelControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeCurrentFrequencyWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = LevelControl::Attributes::CurrentFrequency::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeMinFrequencyWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = LevelControl::Attributes::MinFrequency::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::LevelControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeMinFrequencyWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = LevelControl::Attributes::MinFrequency::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::LevelControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeMinFrequencyWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = LevelControl::Attributes::MinFrequency::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeMaxFrequencyWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = LevelControl::Attributes::MaxFrequency::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::LevelControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeMaxFrequencyWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = LevelControl::Attributes::MaxFrequency::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::LevelControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeMaxFrequencyWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = LevelControl::Attributes::MaxFrequency::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeOptionsWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = LevelControl::Attributes::Options::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::LevelControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeOptionsWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeOptionsWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeOptionsWithValue:(NSNumber * _Nonnull)value
                                params:(MTRWriteParams * _Nullable)params
                     completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = LevelControl::Attributes::Options::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedCharValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::LevelControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeOptionsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                     maxInterval:(NSNumber * _Nonnull)maxInterval
                                          params:(MTRSubscribeParams * _Nullable)params
                         subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                   reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = LevelControl::Attributes::Options::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::LevelControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeOptionsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                      endpoint:(NSNumber *)endpoint
                                         queue:(dispatch_queue_t)queue
                             completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = LevelControl::Attributes::Options::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeOnOffTransitionTimeWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = LevelControl::Attributes::OnOffTransitionTime::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::LevelControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeOnOffTransitionTimeWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeOnOffTransitionTimeWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeOnOffTransitionTimeWithValue:(NSNumber * _Nonnull)value
                                            params:(MTRWriteParams * _Nullable)params
                                 completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = LevelControl::Attributes::OnOffTransitionTime::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::LevelControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeOnOffTransitionTimeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = LevelControl::Attributes::OnOffTransitionTime::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::LevelControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeOnOffTransitionTimeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = LevelControl::Attributes::OnOffTransitionTime::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeOnLevelWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = LevelControl::Attributes::OnLevel::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::LevelControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeOnLevelWithValue:(NSNumber * _Nullable)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeOnLevelWithValue:(NSNumber * _Nullable) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeOnLevelWithValue:(NSNumber * _Nullable)value
                                params:(MTRWriteParams * _Nullable)params
                     completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = LevelControl::Attributes::OnLevel::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.unsignedCharValue;
            }
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::LevelControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeOnLevelWithMinInterval:(NSNumber * _Nonnull)minInterval
                                     maxInterval:(NSNumber * _Nonnull)maxInterval
                                          params:(MTRSubscribeParams * _Nullable)params
                         subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                   reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = LevelControl::Attributes::OnLevel::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::LevelControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeOnLevelWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                      endpoint:(NSNumber *)endpoint
                                         queue:(dispatch_queue_t)queue
                             completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = LevelControl::Attributes::OnLevel::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeOnTransitionTimeWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = LevelControl::Attributes::OnTransitionTime::TypeInfo;
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::LevelControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeOnTransitionTimeWithValue:(NSNumber * _Nullable)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeOnTransitionTimeWithValue:(NSNumber * _Nullable) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeOnTransitionTimeWithValue:(NSNumber * _Nullable)value
                                         params:(MTRWriteParams * _Nullable)params
                              completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = LevelControl::Attributes::OnTransitionTime::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.unsignedShortValue;
            }
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::LevelControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeOnTransitionTimeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                              maxInterval:(NSNumber * _Nonnull)maxInterval
                                                   params:(MTRSubscribeParams * _Nullable)params
                                  subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                            reportHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = LevelControl::Attributes::OnTransitionTime::TypeInfo;
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::LevelControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeOnTransitionTimeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = LevelControl::Attributes::OnTransitionTime::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeOffTransitionTimeWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = LevelControl::Attributes::OffTransitionTime::TypeInfo;
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::LevelControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeOffTransitionTimeWithValue:(NSNumber * _Nullable)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeOffTransitionTimeWithValue:(NSNumber * _Nullable) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeOffTransitionTimeWithValue:(NSNumber * _Nullable)value
                                          params:(MTRWriteParams * _Nullable)params
                               completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = LevelControl::Attributes::OffTransitionTime::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.unsignedShortValue;
            }
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::LevelControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeOffTransitionTimeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = LevelControl::Attributes::OffTransitionTime::TypeInfo;
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::LevelControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeOffTransitionTimeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = LevelControl::Attributes::OffTransitionTime::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeDefaultMoveRateWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = LevelControl::Attributes::DefaultMoveRate::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::LevelControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeDefaultMoveRateWithValue:(NSNumber * _Nullable)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeDefaultMoveRateWithValue:(NSNumber * _Nullable) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeDefaultMoveRateWithValue:(NSNumber * _Nullable)value
                                        params:(MTRWriteParams * _Nullable)params
                             completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = LevelControl::Attributes::DefaultMoveRate::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.unsignedCharValue;
            }
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::LevelControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeDefaultMoveRateWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = LevelControl::Attributes::DefaultMoveRate::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::LevelControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeDefaultMoveRateWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = LevelControl::Attributes::DefaultMoveRate::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeStartUpCurrentLevelWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = LevelControl::Attributes::StartUpCurrentLevel::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::LevelControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeStartUpCurrentLevelWithValue:(NSNumber * _Nullable)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeStartUpCurrentLevelWithValue:(NSNumber * _Nullable) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeStartUpCurrentLevelWithValue:(NSNumber * _Nullable)value
                                            params:(MTRWriteParams * _Nullable)params
                                 completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = LevelControl::Attributes::StartUpCurrentLevel::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.unsignedCharValue;
            }
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::LevelControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeStartUpCurrentLevelWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = LevelControl::Attributes::StartUpCurrentLevel::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::LevelControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeStartUpCurrentLevelWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = LevelControl::Attributes::StartUpCurrentLevel::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRLevelControlGeneratedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = LevelControl::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<LevelControlGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::LevelControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRLevelControlGeneratedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = LevelControl::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<LevelControlGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::LevelControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRLevelControlGeneratedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRLevelControlGeneratedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = LevelControl::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<LevelControlGeneratedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRLevelControlAcceptedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = LevelControl::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<LevelControlAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::LevelControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRLevelControlAcceptedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = LevelControl::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<LevelControlAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::LevelControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRLevelControlAcceptedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRLevelControlAcceptedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = LevelControl::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<LevelControlAcceptedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRLevelControlAttributeListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = LevelControl::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<LevelControlAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::LevelControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRLevelControlAttributeListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = LevelControl::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<LevelControlAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::LevelControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRLevelControlAttributeListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRLevelControlAttributeListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = LevelControl::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<LevelControlAttributeListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = LevelControl::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::LevelControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = LevelControl::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::LevelControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = LevelControl::Attributes::FeatureMap::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = LevelControl::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::LevelControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = LevelControl::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::LevelControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = LevelControl::Attributes::ClusterRevision::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

@end

@implementation MTRBaseClusterBinaryInputBasic

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = endpoint;
    }
    return self;
}

- (void)readAttributeActiveTextWithCompletionHandler:(void (^)(
                                                         NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BinaryInputBasic::Attributes::ActiveText::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BinaryInputBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeActiveTextWithValue:(NSString * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeActiveTextWithValue:(NSString * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeActiveTextWithValue:(NSString * _Nonnull)value
                                   params:(MTRWriteParams * _Nullable)params
                        completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = BinaryInputBasic::Attributes::ActiveText::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = [self asCharSpan:value];
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BinaryInputBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeActiveTextWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRCharStringAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BinaryInputBasic::Attributes::ActiveText::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BinaryInputBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRCharStringAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeActiveTextWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = BinaryInputBasic::Attributes::ActiveText::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeDescriptionWithCompletionHandler:(void (^)(
                                                          NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BinaryInputBasic::Attributes::Description::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BinaryInputBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeDescriptionWithValue:(NSString * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeDescriptionWithValue:(NSString * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeDescriptionWithValue:(NSString * _Nonnull)value
                                    params:(MTRWriteParams * _Nullable)params
                         completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = BinaryInputBasic::Attributes::Description::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = [self asCharSpan:value];
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BinaryInputBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeDescriptionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRCharStringAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BinaryInputBasic::Attributes::Description::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BinaryInputBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRCharStringAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeDescriptionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = BinaryInputBasic::Attributes::Description::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeInactiveTextWithCompletionHandler:(void (^)(
                                                           NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BinaryInputBasic::Attributes::InactiveText::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BinaryInputBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeInactiveTextWithValue:(NSString * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeInactiveTextWithValue:(NSString * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeInactiveTextWithValue:(NSString * _Nonnull)value
                                     params:(MTRWriteParams * _Nullable)params
                          completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = BinaryInputBasic::Attributes::InactiveText::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = [self asCharSpan:value];
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BinaryInputBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeInactiveTextWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRCharStringAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BinaryInputBasic::Attributes::InactiveText::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BinaryInputBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRCharStringAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeInactiveTextWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = BinaryInputBasic::Attributes::InactiveText::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeOutOfServiceWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBooleanAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BinaryInputBasic::Attributes::OutOfService::TypeInfo;
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BinaryInputBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeOutOfServiceWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeOutOfServiceWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeOutOfServiceWithValue:(NSNumber * _Nonnull)value
                                     params:(MTRWriteParams * _Nullable)params
                          completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = BinaryInputBasic::Attributes::OutOfService::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.boolValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BinaryInputBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeOutOfServiceWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRBooleanAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BinaryInputBasic::Attributes::OutOfService::TypeInfo;
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BinaryInputBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRBooleanAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeOutOfServiceWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBooleanAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = BinaryInputBasic::Attributes::OutOfService::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributePolarityWithCompletionHandler:(void (^)(
                                                       NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BinaryInputBasic::Attributes::Polarity::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BinaryInputBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributePolarityWithMinInterval:(NSNumber * _Nonnull)minInterval
                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                           params:(MTRSubscribeParams * _Nullable)params
                          subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BinaryInputBasic::Attributes::Polarity::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BinaryInputBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributePolarityWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                       endpoint:(NSNumber *)endpoint
                                          queue:(dispatch_queue_t)queue
                              completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = BinaryInputBasic::Attributes::Polarity::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributePresentValueWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBooleanAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BinaryInputBasic::Attributes::PresentValue::TypeInfo;
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BinaryInputBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributePresentValueWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributePresentValueWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributePresentValueWithValue:(NSNumber * _Nonnull)value
                                     params:(MTRWriteParams * _Nullable)params
                          completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = BinaryInputBasic::Attributes::PresentValue::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.boolValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BinaryInputBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributePresentValueWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRBooleanAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BinaryInputBasic::Attributes::PresentValue::TypeInfo;
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BinaryInputBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRBooleanAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributePresentValueWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBooleanAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = BinaryInputBasic::Attributes::PresentValue::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeReliabilityWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BinaryInputBasic::Attributes::Reliability::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BinaryInputBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeReliabilityWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeReliabilityWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeReliabilityWithValue:(NSNumber * _Nonnull)value
                                    params:(MTRWriteParams * _Nullable)params
                         completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = BinaryInputBasic::Attributes::Reliability::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedCharValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BinaryInputBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeReliabilityWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BinaryInputBasic::Attributes::Reliability::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BinaryInputBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeReliabilityWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = BinaryInputBasic::Attributes::Reliability::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeStatusFlagsWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BinaryInputBasic::Attributes::StatusFlags::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BinaryInputBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeStatusFlagsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BinaryInputBasic::Attributes::StatusFlags::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BinaryInputBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeStatusFlagsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = BinaryInputBasic::Attributes::StatusFlags::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeApplicationTypeWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BinaryInputBasic::Attributes::ApplicationType::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BinaryInputBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeApplicationTypeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BinaryInputBasic::Attributes::ApplicationType::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BinaryInputBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeApplicationTypeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = BinaryInputBasic::Attributes::ApplicationType::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRBinaryInputBasicGeneratedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BinaryInputBasic::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<BinaryInputBasicGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BinaryInputBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRBinaryInputBasicGeneratedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BinaryInputBasic::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<BinaryInputBasicGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BinaryInputBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRBinaryInputBasicGeneratedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBinaryInputBasicGeneratedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BinaryInputBasic::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<BinaryInputBasicGeneratedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRBinaryInputBasicAcceptedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BinaryInputBasic::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<BinaryInputBasicAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BinaryInputBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRBinaryInputBasicAcceptedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BinaryInputBasic::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<BinaryInputBasicAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BinaryInputBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRBinaryInputBasicAcceptedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBinaryInputBasicAcceptedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BinaryInputBasic::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<BinaryInputBasicAcceptedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBinaryInputBasicAttributeListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BinaryInputBasic::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<BinaryInputBasicAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BinaryInputBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRBinaryInputBasicAttributeListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BinaryInputBasic::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<BinaryInputBasicAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BinaryInputBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRBinaryInputBasicAttributeListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBinaryInputBasicAttributeListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BinaryInputBasic::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<BinaryInputBasicAttributeListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BinaryInputBasic::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BinaryInputBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BinaryInputBasic::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BinaryInputBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = BinaryInputBasic::Attributes::FeatureMap::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BinaryInputBasic::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BinaryInputBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BinaryInputBasic::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BinaryInputBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = BinaryInputBasic::Attributes::ClusterRevision::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

@end

@implementation MTRBaseClusterDescriptor

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = endpoint;
    }
    return self;
}

- (void)readAttributeDeviceListWithCompletionHandler:(void (^)(
                                                         NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRDescriptorDeviceListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Descriptor::Attributes::DeviceList::TypeInfo;
            auto successFn = Callback<DescriptorDeviceListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DescriptorCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeDeviceListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRDescriptorDeviceListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Descriptor::Attributes::DeviceList::TypeInfo;
            auto successFn = Callback<DescriptorDeviceListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::DescriptorCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRDescriptorDeviceListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeDeviceListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRDescriptorDeviceListListAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Descriptor::Attributes::DeviceList::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<DescriptorDeviceListListAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeServerListWithCompletionHandler:(void (^)(
                                                         NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRDescriptorServerListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Descriptor::Attributes::ServerList::TypeInfo;
            auto successFn = Callback<DescriptorServerListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DescriptorCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeServerListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRDescriptorServerListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Descriptor::Attributes::ServerList::TypeInfo;
            auto successFn = Callback<DescriptorServerListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::DescriptorCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRDescriptorServerListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeServerListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRDescriptorServerListListAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Descriptor::Attributes::ServerList::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<DescriptorServerListListAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeClientListWithCompletionHandler:(void (^)(
                                                         NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRDescriptorClientListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Descriptor::Attributes::ClientList::TypeInfo;
            auto successFn = Callback<DescriptorClientListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DescriptorCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeClientListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRDescriptorClientListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Descriptor::Attributes::ClientList::TypeInfo;
            auto successFn = Callback<DescriptorClientListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::DescriptorCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRDescriptorClientListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeClientListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRDescriptorClientListListAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Descriptor::Attributes::ClientList::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<DescriptorClientListListAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributePartsListWithCompletionHandler:(void (^)(
                                                        NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRDescriptorPartsListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Descriptor::Attributes::PartsList::TypeInfo;
            auto successFn = Callback<DescriptorPartsListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DescriptorCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributePartsListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRDescriptorPartsListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Descriptor::Attributes::PartsList::TypeInfo;
            auto successFn = Callback<DescriptorPartsListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::DescriptorCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRDescriptorPartsListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributePartsListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRDescriptorPartsListListAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Descriptor::Attributes::PartsList::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<DescriptorPartsListListAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRDescriptorGeneratedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Descriptor::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<DescriptorGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DescriptorCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRDescriptorGeneratedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Descriptor::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<DescriptorGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::DescriptorCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRDescriptorGeneratedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRDescriptorGeneratedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Descriptor::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<DescriptorGeneratedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRDescriptorAcceptedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Descriptor::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<DescriptorAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DescriptorCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRDescriptorAcceptedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Descriptor::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<DescriptorAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::DescriptorCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRDescriptorAcceptedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRDescriptorAcceptedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Descriptor::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<DescriptorAcceptedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRDescriptorAttributeListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Descriptor::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<DescriptorAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DescriptorCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRDescriptorAttributeListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Descriptor::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<DescriptorAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::DescriptorCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRDescriptorAttributeListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRDescriptorAttributeListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Descriptor::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<DescriptorAttributeListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Descriptor::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DescriptorCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Descriptor::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::DescriptorCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Descriptor::Attributes::FeatureMap::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Descriptor::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DescriptorCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Descriptor::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::DescriptorCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Descriptor::Attributes::ClusterRevision::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

@end

@implementation MTRBaseClusterBinding

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = endpoint;
    }
    return self;
}

- (void)readAttributeBindingWithParams:(MTRReadParams * _Nullable)params
                     completionHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{ // Make a copy of params before we go async.
    params = [params copy];
    new MTRBindingBindingListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Binding::Attributes::Binding::TypeInfo;
            auto successFn = Callback<BindingBindingListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BindingCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue]);
        });
}

- (void)writeAttributeBindingWithValue:(NSArray * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeBindingWithValue:(NSArray * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeBindingWithValue:(NSArray * _Nonnull)value
                                params:(MTRWriteParams * _Nullable)params
                     completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = Binding::Attributes::Binding::TypeInfo;
            TypeInfo::Type cppValue;
            {
                using ListType_0 = std::remove_reference_t<decltype(cppValue)>;
                using ListMemberType_0 = ListMemberTypeGetter<ListType_0>::Type;
                if (value.count != 0) {
                    auto * listHolder_0 = new ListHolder<ListMemberType_0>(value.count);
                    if (listHolder_0 == nullptr || listHolder_0->mList == nullptr) {
                        return CHIP_ERROR_INVALID_ARGUMENT;
                    }
                    listFreer.add(listHolder_0);
                    for (size_t i_0 = 0; i_0 < value.count; ++i_0) {
                        if (![value[i_0] isKindOfClass:[MTRBindingClusterTargetStruct class]]) {
                            // Wrong kind of value.
                            return CHIP_ERROR_INVALID_ARGUMENT;
                        }
                        auto element_0 = (MTRBindingClusterTargetStruct *) value[i_0];
                        if (element_0.node != nil) {
                            auto & definedValue_2 = listHolder_0->mList[i_0].node.Emplace();
                            definedValue_2 = element_0.node.unsignedLongLongValue;
                        }
                        if (element_0.group != nil) {
                            auto & definedValue_2 = listHolder_0->mList[i_0].group.Emplace();
                            definedValue_2 = element_0.group.unsignedShortValue;
                        }
                        if (element_0.endpoint != nil) {
                            auto & definedValue_2 = listHolder_0->mList[i_0].endpoint.Emplace();
                            definedValue_2 = element_0.endpoint.unsignedShortValue;
                        }
                        if (element_0.cluster != nil) {
                            auto & definedValue_2 = listHolder_0->mList[i_0].cluster.Emplace();
                            definedValue_2 = element_0.cluster.unsignedIntValue;
                        }
                        listHolder_0->mList[i_0].fabricIndex = element_0.fabricIndex.unsignedCharValue;
                    }
                    cppValue = ListType_0(listHolder_0->mList, value.count);
                } else {
                    cppValue = ListType_0();
                }
            }
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BindingCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeBindingWithMinInterval:(NSNumber * _Nonnull)minInterval
                                     maxInterval:(NSNumber * _Nonnull)maxInterval
                                          params:(MTRSubscribeParams * _Nullable)params
                         subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                   reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRBindingBindingListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Binding::Attributes::Binding::TypeInfo;
            auto successFn = Callback<BindingBindingListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BindingCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRBindingBindingListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeBindingWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                      endpoint:(NSNumber *)endpoint
                                         queue:(dispatch_queue_t)queue
                             completionHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBindingBindingListAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Binding::Attributes::Binding::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<BindingBindingListAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRBindingGeneratedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Binding::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<BindingGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BindingCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRBindingGeneratedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Binding::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<BindingGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BindingCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRBindingGeneratedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBindingGeneratedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Binding::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<BindingGeneratedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRBindingAcceptedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Binding::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<BindingAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BindingCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRBindingAcceptedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Binding::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<BindingAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BindingCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRBindingAcceptedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBindingAcceptedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Binding::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<BindingAcceptedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBindingAttributeListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Binding::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<BindingAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BindingCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRBindingAttributeListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Binding::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<BindingAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BindingCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRBindingAttributeListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBindingAttributeListListAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Binding::Attributes::AttributeList::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<BindingAttributeListListAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Binding::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BindingCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Binding::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BindingCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Binding::Attributes::FeatureMap::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Binding::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BindingCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Binding::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BindingCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Binding::Attributes::ClusterRevision::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

@end

@implementation MTRBaseClusterAccessControl

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = endpoint;
    }
    return self;
}

- (void)readAttributeAclWithParams:(MTRReadParams * _Nullable)params
                 completionHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{ // Make a copy of params before we go async.
    params = [params copy];
    new MTRAccessControlAclListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = AccessControl::Attributes::Acl::TypeInfo;
            auto successFn = Callback<AccessControlAclListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::AccessControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue]);
        });
}

- (void)writeAttributeAclWithValue:(NSArray * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeAclWithValue:(NSArray * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeAclWithValue:(NSArray * _Nonnull)value
                            params:(MTRWriteParams * _Nullable)params
                 completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = AccessControl::Attributes::Acl::TypeInfo;
            TypeInfo::Type cppValue;
            {
                using ListType_0 = std::remove_reference_t<decltype(cppValue)>;
                using ListMemberType_0 = ListMemberTypeGetter<ListType_0>::Type;
                if (value.count != 0) {
                    auto * listHolder_0 = new ListHolder<ListMemberType_0>(value.count);
                    if (listHolder_0 == nullptr || listHolder_0->mList == nullptr) {
                        return CHIP_ERROR_INVALID_ARGUMENT;
                    }
                    listFreer.add(listHolder_0);
                    for (size_t i_0 = 0; i_0 < value.count; ++i_0) {
                        if (![value[i_0] isKindOfClass:[MTRAccessControlClusterAccessControlEntry class]]) {
                            // Wrong kind of value.
                            return CHIP_ERROR_INVALID_ARGUMENT;
                        }
                        auto element_0 = (MTRAccessControlClusterAccessControlEntry *) value[i_0];
                        listHolder_0->mList[i_0].privilege
                            = static_cast<std::remove_reference_t<decltype(listHolder_0->mList[i_0].privilege)>>(
                                element_0.privilege.unsignedCharValue);
                        listHolder_0->mList[i_0].authMode
                            = static_cast<std::remove_reference_t<decltype(listHolder_0->mList[i_0].authMode)>>(
                                element_0.authMode.unsignedCharValue);
                        if (element_0.subjects == nil) {
                            listHolder_0->mList[i_0].subjects.SetNull();
                        } else {
                            auto & nonNullValue_2 = listHolder_0->mList[i_0].subjects.SetNonNull();
                            {
                                using ListType_3 = std::remove_reference_t<decltype(nonNullValue_2)>;
                                using ListMemberType_3 = ListMemberTypeGetter<ListType_3>::Type;
                                if (element_0.subjects.count != 0) {
                                    auto * listHolder_3 = new ListHolder<ListMemberType_3>(element_0.subjects.count);
                                    if (listHolder_3 == nullptr || listHolder_3->mList == nullptr) {
                                        return CHIP_ERROR_INVALID_ARGUMENT;
                                    }
                                    listFreer.add(listHolder_3);
                                    for (size_t i_3 = 0; i_3 < element_0.subjects.count; ++i_3) {
                                        if (![element_0.subjects[i_3] isKindOfClass:[NSNumber class]]) {
                                            // Wrong kind of value.
                                            return CHIP_ERROR_INVALID_ARGUMENT;
                                        }
                                        auto element_3 = (NSNumber *) element_0.subjects[i_3];
                                        listHolder_3->mList[i_3] = element_3.unsignedLongLongValue;
                                    }
                                    nonNullValue_2 = ListType_3(listHolder_3->mList, element_0.subjects.count);
                                } else {
                                    nonNullValue_2 = ListType_3();
                                }
                            }
                        }
                        if (element_0.targets == nil) {
                            listHolder_0->mList[i_0].targets.SetNull();
                        } else {
                            auto & nonNullValue_2 = listHolder_0->mList[i_0].targets.SetNonNull();
                            {
                                using ListType_3 = std::remove_reference_t<decltype(nonNullValue_2)>;
                                using ListMemberType_3 = ListMemberTypeGetter<ListType_3>::Type;
                                if (element_0.targets.count != 0) {
                                    auto * listHolder_3 = new ListHolder<ListMemberType_3>(element_0.targets.count);
                                    if (listHolder_3 == nullptr || listHolder_3->mList == nullptr) {
                                        return CHIP_ERROR_INVALID_ARGUMENT;
                                    }
                                    listFreer.add(listHolder_3);
                                    for (size_t i_3 = 0; i_3 < element_0.targets.count; ++i_3) {
                                        if (![element_0.targets[i_3] isKindOfClass:[MTRAccessControlClusterTarget class]]) {
                                            // Wrong kind of value.
                                            return CHIP_ERROR_INVALID_ARGUMENT;
                                        }
                                        auto element_3 = (MTRAccessControlClusterTarget *) element_0.targets[i_3];
                                        if (element_3.cluster == nil) {
                                            listHolder_3->mList[i_3].cluster.SetNull();
                                        } else {
                                            auto & nonNullValue_5 = listHolder_3->mList[i_3].cluster.SetNonNull();
                                            nonNullValue_5 = element_3.cluster.unsignedIntValue;
                                        }
                                        if (element_3.endpoint == nil) {
                                            listHolder_3->mList[i_3].endpoint.SetNull();
                                        } else {
                                            auto & nonNullValue_5 = listHolder_3->mList[i_3].endpoint.SetNonNull();
                                            nonNullValue_5 = element_3.endpoint.unsignedShortValue;
                                        }
                                        if (element_3.deviceType == nil) {
                                            listHolder_3->mList[i_3].deviceType.SetNull();
                                        } else {
                                            auto & nonNullValue_5 = listHolder_3->mList[i_3].deviceType.SetNonNull();
                                            nonNullValue_5 = element_3.deviceType.unsignedIntValue;
                                        }
                                    }
                                    nonNullValue_2 = ListType_3(listHolder_3->mList, element_0.targets.count);
                                } else {
                                    nonNullValue_2 = ListType_3();
                                }
                            }
                        }
                        listHolder_0->mList[i_0].fabricIndex = element_0.fabricIndex.unsignedCharValue;
                    }
                    cppValue = ListType_0(listHolder_0->mList, value.count);
                } else {
                    cppValue = ListType_0();
                }
            }
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::AccessControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeAclWithMinInterval:(NSNumber * _Nonnull)minInterval
                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                      params:(MTRSubscribeParams * _Nullable)params
                     subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                               reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRAccessControlAclListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = AccessControl::Attributes::Acl::TypeInfo;
            auto successFn = Callback<AccessControlAclListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::AccessControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRAccessControlAclListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAclWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                  endpoint:(NSNumber *)endpoint
                                     queue:(dispatch_queue_t)queue
                         completionHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRAccessControlAclListAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = AccessControl::Attributes::Acl::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<AccessControlAclListAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeExtensionWithParams:(MTRReadParams * _Nullable)params
                       completionHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{ // Make a copy of params before we go async.
    params = [params copy];
    new MTRAccessControlExtensionListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = AccessControl::Attributes::Extension::TypeInfo;
            auto successFn = Callback<AccessControlExtensionListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::AccessControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue]);
        });
}

- (void)writeAttributeExtensionWithValue:(NSArray * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeExtensionWithValue:(NSArray * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeExtensionWithValue:(NSArray * _Nonnull)value
                                  params:(MTRWriteParams * _Nullable)params
                       completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = AccessControl::Attributes::Extension::TypeInfo;
            TypeInfo::Type cppValue;
            {
                using ListType_0 = std::remove_reference_t<decltype(cppValue)>;
                using ListMemberType_0 = ListMemberTypeGetter<ListType_0>::Type;
                if (value.count != 0) {
                    auto * listHolder_0 = new ListHolder<ListMemberType_0>(value.count);
                    if (listHolder_0 == nullptr || listHolder_0->mList == nullptr) {
                        return CHIP_ERROR_INVALID_ARGUMENT;
                    }
                    listFreer.add(listHolder_0);
                    for (size_t i_0 = 0; i_0 < value.count; ++i_0) {
                        if (![value[i_0] isKindOfClass:[MTRAccessControlClusterExtensionEntry class]]) {
                            // Wrong kind of value.
                            return CHIP_ERROR_INVALID_ARGUMENT;
                        }
                        auto element_0 = (MTRAccessControlClusterExtensionEntry *) value[i_0];
                        listHolder_0->mList[i_0].data = [self asByteSpan:element_0.data];
                        listHolder_0->mList[i_0].fabricIndex = element_0.fabricIndex.unsignedCharValue;
                    }
                    cppValue = ListType_0(listHolder_0->mList, value.count);
                } else {
                    cppValue = ListType_0();
                }
            }
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::AccessControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeExtensionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRAccessControlExtensionListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = AccessControl::Attributes::Extension::TypeInfo;
            auto successFn = Callback<AccessControlExtensionListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::AccessControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRAccessControlExtensionListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeExtensionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRAccessControlExtensionListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = AccessControl::Attributes::Extension::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<AccessControlExtensionListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeSubjectsPerAccessControlEntryWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                            NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = AccessControl::Attributes::SubjectsPerAccessControlEntry::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::AccessControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeSubjectsPerAccessControlEntryWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                params:(MTRSubscribeParams * _Nullable)params
                                               subscriptionEstablished:
                                                   (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                         reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = AccessControl::Attributes::SubjectsPerAccessControlEntry::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::AccessControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeSubjectsPerAccessControlEntryWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                            endpoint:(NSNumber *)endpoint
                                                               queue:(dispatch_queue_t)queue
                                                   completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = AccessControl::Attributes::SubjectsPerAccessControlEntry::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeTargetsPerAccessControlEntryWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = AccessControl::Attributes::TargetsPerAccessControlEntry::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::AccessControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeTargetsPerAccessControlEntryWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                                               params:(MTRSubscribeParams * _Nullable)params
                                              subscriptionEstablished:
                                                  (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                        reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                          NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = AccessControl::Attributes::TargetsPerAccessControlEntry::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::AccessControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeTargetsPerAccessControlEntryWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                           endpoint:(NSNumber *)endpoint
                                                              queue:(dispatch_queue_t)queue
                                                  completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = AccessControl::Attributes::TargetsPerAccessControlEntry::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeAccessControlEntriesPerFabricWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                            NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = AccessControl::Attributes::AccessControlEntriesPerFabric::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::AccessControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAccessControlEntriesPerFabricWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                params:(MTRSubscribeParams * _Nullable)params
                                               subscriptionEstablished:
                                                   (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                         reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = AccessControl::Attributes::AccessControlEntriesPerFabric::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::AccessControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAccessControlEntriesPerFabricWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                            endpoint:(NSNumber *)endpoint
                                                               queue:(dispatch_queue_t)queue
                                                   completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = AccessControl::Attributes::AccessControlEntriesPerFabric::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRAccessControlGeneratedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = AccessControl::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<AccessControlGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::AccessControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRAccessControlGeneratedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = AccessControl::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<AccessControlGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::AccessControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRAccessControlGeneratedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRAccessControlGeneratedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = AccessControl::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<AccessControlGeneratedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRAccessControlAcceptedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = AccessControl::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<AccessControlAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::AccessControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRAccessControlAcceptedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = AccessControl::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<AccessControlAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::AccessControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRAccessControlAcceptedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRAccessControlAcceptedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = AccessControl::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<AccessControlAcceptedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRAccessControlAttributeListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = AccessControl::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<AccessControlAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::AccessControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRAccessControlAttributeListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = AccessControl::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<AccessControlAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::AccessControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRAccessControlAttributeListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRAccessControlAttributeListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = AccessControl::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<AccessControlAttributeListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = AccessControl::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::AccessControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = AccessControl::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::AccessControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = AccessControl::Attributes::FeatureMap::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = AccessControl::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::AccessControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = AccessControl::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::AccessControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = AccessControl::Attributes::ClusterRevision::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

@end

@implementation MTRBaseClusterBridgedActions

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = endpoint;
    }
    return self;
}

- (void)instantActionWithParams:(MTRBridgedActionsClusterInstantActionParams *)params
              completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            BridgedActions::Commands::InstantAction::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.actionID = params.actionID.unsignedShortValue;
            if (params.invokeID != nil) {
                auto & definedValue_0 = request.invokeID.Emplace();
                definedValue_0 = params.invokeID.unsignedIntValue;
            }

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BridgedActionsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)instantActionWithTransitionWithParams:(MTRBridgedActionsClusterInstantActionWithTransitionParams *)params
                            completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            BridgedActions::Commands::InstantActionWithTransition::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.actionID = params.actionID.unsignedShortValue;
            if (params.invokeID != nil) {
                auto & definedValue_0 = request.invokeID.Emplace();
                definedValue_0 = params.invokeID.unsignedIntValue;
            }
            request.transitionTime = params.transitionTime.unsignedShortValue;

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BridgedActionsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)startActionWithParams:(MTRBridgedActionsClusterStartActionParams *)params
            completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            BridgedActions::Commands::StartAction::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.actionID = params.actionID.unsignedShortValue;
            if (params.invokeID != nil) {
                auto & definedValue_0 = request.invokeID.Emplace();
                definedValue_0 = params.invokeID.unsignedIntValue;
            }

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BridgedActionsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)startActionWithDurationWithParams:(MTRBridgedActionsClusterStartActionWithDurationParams *)params
                        completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            BridgedActions::Commands::StartActionWithDuration::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.actionID = params.actionID.unsignedShortValue;
            if (params.invokeID != nil) {
                auto & definedValue_0 = request.invokeID.Emplace();
                definedValue_0 = params.invokeID.unsignedIntValue;
            }
            request.duration = params.duration.unsignedIntValue;

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BridgedActionsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)stopActionWithParams:(MTRBridgedActionsClusterStopActionParams *)params
           completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            BridgedActions::Commands::StopAction::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.actionID = params.actionID.unsignedShortValue;
            if (params.invokeID != nil) {
                auto & definedValue_0 = request.invokeID.Emplace();
                definedValue_0 = params.invokeID.unsignedIntValue;
            }

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BridgedActionsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)pauseActionWithParams:(MTRBridgedActionsClusterPauseActionParams *)params
            completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            BridgedActions::Commands::PauseAction::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.actionID = params.actionID.unsignedShortValue;
            if (params.invokeID != nil) {
                auto & definedValue_0 = request.invokeID.Emplace();
                definedValue_0 = params.invokeID.unsignedIntValue;
            }

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BridgedActionsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)pauseActionWithDurationWithParams:(MTRBridgedActionsClusterPauseActionWithDurationParams *)params
                        completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            BridgedActions::Commands::PauseActionWithDuration::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.actionID = params.actionID.unsignedShortValue;
            if (params.invokeID != nil) {
                auto & definedValue_0 = request.invokeID.Emplace();
                definedValue_0 = params.invokeID.unsignedIntValue;
            }
            request.duration = params.duration.unsignedIntValue;

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BridgedActionsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)resumeActionWithParams:(MTRBridgedActionsClusterResumeActionParams *)params
             completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            BridgedActions::Commands::ResumeAction::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.actionID = params.actionID.unsignedShortValue;
            if (params.invokeID != nil) {
                auto & definedValue_0 = request.invokeID.Emplace();
                definedValue_0 = params.invokeID.unsignedIntValue;
            }

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BridgedActionsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)enableActionWithParams:(MTRBridgedActionsClusterEnableActionParams *)params
             completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            BridgedActions::Commands::EnableAction::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.actionID = params.actionID.unsignedShortValue;
            if (params.invokeID != nil) {
                auto & definedValue_0 = request.invokeID.Emplace();
                definedValue_0 = params.invokeID.unsignedIntValue;
            }

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BridgedActionsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)enableActionWithDurationWithParams:(MTRBridgedActionsClusterEnableActionWithDurationParams *)params
                         completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            BridgedActions::Commands::EnableActionWithDuration::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.actionID = params.actionID.unsignedShortValue;
            if (params.invokeID != nil) {
                auto & definedValue_0 = request.invokeID.Emplace();
                definedValue_0 = params.invokeID.unsignedIntValue;
            }
            request.duration = params.duration.unsignedIntValue;

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BridgedActionsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)disableActionWithParams:(MTRBridgedActionsClusterDisableActionParams *)params
              completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            BridgedActions::Commands::DisableAction::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.actionID = params.actionID.unsignedShortValue;
            if (params.invokeID != nil) {
                auto & definedValue_0 = request.invokeID.Emplace();
                definedValue_0 = params.invokeID.unsignedIntValue;
            }

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BridgedActionsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)disableActionWithDurationWithParams:(MTRBridgedActionsClusterDisableActionWithDurationParams *)params
                          completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            BridgedActions::Commands::DisableActionWithDuration::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.actionID = params.actionID.unsignedShortValue;
            if (params.invokeID != nil) {
                auto & definedValue_0 = request.invokeID.Emplace();
                definedValue_0 = params.invokeID.unsignedIntValue;
            }
            request.duration = params.duration.unsignedIntValue;

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BridgedActionsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)readAttributeActionListWithCompletionHandler:(void (^)(
                                                         NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBridgedActionsActionListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BridgedActions::Attributes::ActionList::TypeInfo;
            auto successFn = Callback<BridgedActionsActionListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BridgedActionsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeActionListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRBridgedActionsActionListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BridgedActions::Attributes::ActionList::TypeInfo;
            auto successFn = Callback<BridgedActionsActionListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BridgedActionsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRBridgedActionsActionListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeActionListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBridgedActionsActionListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BridgedActions::Attributes::ActionList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<BridgedActionsActionListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEndpointListWithCompletionHandler:(void (^)(
                                                           NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBridgedActionsEndpointListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BridgedActions::Attributes::EndpointList::TypeInfo;
            auto successFn = Callback<BridgedActionsEndpointListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BridgedActionsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeEndpointListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRBridgedActionsEndpointListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BridgedActions::Attributes::EndpointList::TypeInfo;
            auto successFn = Callback<BridgedActionsEndpointListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BridgedActionsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRBridgedActionsEndpointListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeEndpointListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBridgedActionsEndpointListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BridgedActions::Attributes::EndpointList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<BridgedActionsEndpointListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeSetupUrlWithCompletionHandler:(void (^)(
                                                       NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BridgedActions::Attributes::SetupUrl::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BridgedActionsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeSetupUrlWithMinInterval:(NSNumber * _Nonnull)minInterval
                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                           params:(MTRSubscribeParams * _Nullable)params
                          subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                    reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRCharStringAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BridgedActions::Attributes::SetupUrl::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BridgedActionsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRCharStringAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeSetupUrlWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                       endpoint:(NSNumber *)endpoint
                                          queue:(dispatch_queue_t)queue
                              completionHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = BridgedActions::Attributes::SetupUrl::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRBridgedActionsGeneratedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BridgedActions::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<BridgedActionsGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BridgedActionsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRBridgedActionsGeneratedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BridgedActions::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<BridgedActionsGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BridgedActionsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRBridgedActionsGeneratedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBridgedActionsGeneratedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BridgedActions::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<BridgedActionsGeneratedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRBridgedActionsAcceptedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BridgedActions::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<BridgedActionsAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BridgedActionsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRBridgedActionsAcceptedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BridgedActions::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<BridgedActionsAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BridgedActionsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRBridgedActionsAcceptedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBridgedActionsAcceptedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BridgedActions::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<BridgedActionsAcceptedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBridgedActionsAttributeListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BridgedActions::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<BridgedActionsAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BridgedActionsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRBridgedActionsAttributeListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BridgedActions::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<BridgedActionsAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BridgedActionsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRBridgedActionsAttributeListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBridgedActionsAttributeListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BridgedActions::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<BridgedActionsAttributeListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BridgedActions::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BridgedActionsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BridgedActions::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BridgedActionsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = BridgedActions::Attributes::FeatureMap::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BridgedActions::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BridgedActionsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BridgedActions::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BridgedActionsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = BridgedActions::Attributes::ClusterRevision::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

@end

@implementation MTRBaseClusterBasic

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = endpoint;
    }
    return self;
}

- (void)mfgSpecificPingWithCompletionHandler:(StatusCompletion)completionHandler
{
    [self mfgSpecificPingWithParams:nil completionHandler:completionHandler];
}
- (void)mfgSpecificPingWithParams:(MTRBasicClusterMfgSpecificPingParams * _Nullable)params
                completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            Basic::Commands::MfgSpecificPing::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)readAttributeDataModelRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Basic::Attributes::DataModelRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeDataModelRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Basic::Attributes::DataModelRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeDataModelRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Basic::Attributes::DataModelRevision::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeVendorNameWithCompletionHandler:(void (^)(
                                                         NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Basic::Attributes::VendorName::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeVendorNameWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRCharStringAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Basic::Attributes::VendorName::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRCharStringAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeVendorNameWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Basic::Attributes::VendorName::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeVendorIDWithCompletionHandler:(void (^)(
                                                       NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRVendorIdAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Basic::Attributes::VendorID::TypeInfo;
            auto successFn = Callback<VendorIdAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeVendorIDWithMinInterval:(NSNumber * _Nonnull)minInterval
                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                           params:(MTRSubscribeParams * _Nullable)params
                          subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRVendorIdAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Basic::Attributes::VendorID::TypeInfo;
            auto successFn = Callback<VendorIdAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRVendorIdAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeVendorIDWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                       endpoint:(NSNumber *)endpoint
                                          queue:(dispatch_queue_t)queue
                              completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRVendorIdAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Basic::Attributes::VendorID::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<VendorIdAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeProductNameWithCompletionHandler:(void (^)(
                                                          NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Basic::Attributes::ProductName::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeProductNameWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRCharStringAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Basic::Attributes::ProductName::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRCharStringAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeProductNameWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Basic::Attributes::ProductName::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeProductIDWithCompletionHandler:(void (^)(
                                                        NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Basic::Attributes::ProductID::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeProductIDWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Basic::Attributes::ProductID::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeProductIDWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Basic::Attributes::ProductID::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeNodeLabelWithCompletionHandler:(void (^)(
                                                        NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Basic::Attributes::NodeLabel::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeNodeLabelWithValue:(NSString * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeNodeLabelWithValue:(NSString * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeNodeLabelWithValue:(NSString * _Nonnull)value
                                  params:(MTRWriteParams * _Nullable)params
                       completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = Basic::Attributes::NodeLabel::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = [self asCharSpan:value];
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeNodeLabelWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRCharStringAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Basic::Attributes::NodeLabel::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRCharStringAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeNodeLabelWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Basic::Attributes::NodeLabel::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeLocationWithCompletionHandler:(void (^)(
                                                       NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Basic::Attributes::Location::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeLocationWithValue:(NSString * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeLocationWithValue:(NSString * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeLocationWithValue:(NSString * _Nonnull)value
                                 params:(MTRWriteParams * _Nullable)params
                      completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = Basic::Attributes::Location::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = [self asCharSpan:value];
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeLocationWithMinInterval:(NSNumber * _Nonnull)minInterval
                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                           params:(MTRSubscribeParams * _Nullable)params
                          subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                    reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRCharStringAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Basic::Attributes::Location::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRCharStringAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeLocationWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                       endpoint:(NSNumber *)endpoint
                                          queue:(dispatch_queue_t)queue
                              completionHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Basic::Attributes::Location::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeHardwareVersionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Basic::Attributes::HardwareVersion::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeHardwareVersionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Basic::Attributes::HardwareVersion::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeHardwareVersionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Basic::Attributes::HardwareVersion::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeHardwareVersionStringWithCompletionHandler:(void (^)(NSString * _Nullable value,
                                                                    NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Basic::Attributes::HardwareVersionString::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeHardwareVersionStringWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                   maxInterval:(NSNumber * _Nonnull)maxInterval
                                                        params:(MTRSubscribeParams * _Nullable)params
                                       subscriptionEstablished:
                                           (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                 reportHandler:
                                                     (void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRCharStringAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Basic::Attributes::HardwareVersionString::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRCharStringAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeHardwareVersionStringWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                           completionHandler:
                                               (void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Basic::Attributes::HardwareVersionString::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeSoftwareVersionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Basic::Attributes::SoftwareVersion::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeSoftwareVersionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Basic::Attributes::SoftwareVersion::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeSoftwareVersionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Basic::Attributes::SoftwareVersion::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeSoftwareVersionStringWithCompletionHandler:(void (^)(NSString * _Nullable value,
                                                                    NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Basic::Attributes::SoftwareVersionString::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeSoftwareVersionStringWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                   maxInterval:(NSNumber * _Nonnull)maxInterval
                                                        params:(MTRSubscribeParams * _Nullable)params
                                       subscriptionEstablished:
                                           (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                 reportHandler:
                                                     (void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRCharStringAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Basic::Attributes::SoftwareVersionString::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRCharStringAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeSoftwareVersionStringWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                           completionHandler:
                                               (void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Basic::Attributes::SoftwareVersionString::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeManufacturingDateWithCompletionHandler:(void (^)(NSString * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Basic::Attributes::ManufacturingDate::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeManufacturingDateWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRCharStringAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Basic::Attributes::ManufacturingDate::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRCharStringAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeManufacturingDateWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Basic::Attributes::ManufacturingDate::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributePartNumberWithCompletionHandler:(void (^)(
                                                         NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Basic::Attributes::PartNumber::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributePartNumberWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRCharStringAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Basic::Attributes::PartNumber::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRCharStringAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributePartNumberWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Basic::Attributes::PartNumber::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeProductURLWithCompletionHandler:(void (^)(
                                                         NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Basic::Attributes::ProductURL::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeProductURLWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRCharStringAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Basic::Attributes::ProductURL::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRCharStringAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeProductURLWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Basic::Attributes::ProductURL::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeProductLabelWithCompletionHandler:(void (^)(
                                                           NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Basic::Attributes::ProductLabel::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeProductLabelWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRCharStringAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Basic::Attributes::ProductLabel::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRCharStringAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeProductLabelWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Basic::Attributes::ProductLabel::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeSerialNumberWithCompletionHandler:(void (^)(
                                                           NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Basic::Attributes::SerialNumber::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeSerialNumberWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRCharStringAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Basic::Attributes::SerialNumber::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRCharStringAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeSerialNumberWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Basic::Attributes::SerialNumber::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeLocalConfigDisabledWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRBooleanAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Basic::Attributes::LocalConfigDisabled::TypeInfo;
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeLocalConfigDisabledWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeLocalConfigDisabledWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeLocalConfigDisabledWithValue:(NSNumber * _Nonnull)value
                                            params:(MTRWriteParams * _Nullable)params
                                 completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = Basic::Attributes::LocalConfigDisabled::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.boolValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeLocalConfigDisabledWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRBooleanAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Basic::Attributes::LocalConfigDisabled::TypeInfo;
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRBooleanAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeLocalConfigDisabledWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBooleanAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Basic::Attributes::LocalConfigDisabled::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeReachableWithCompletionHandler:(void (^)(
                                                        NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBooleanAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Basic::Attributes::Reachable::TypeInfo;
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeReachableWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRBooleanAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Basic::Attributes::Reachable::TypeInfo;
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRBooleanAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeReachableWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBooleanAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Basic::Attributes::Reachable::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeUniqueIDWithCompletionHandler:(void (^)(
                                                       NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Basic::Attributes::UniqueID::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeUniqueIDWithMinInterval:(NSNumber * _Nonnull)minInterval
                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                           params:(MTRSubscribeParams * _Nullable)params
                          subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                    reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRCharStringAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Basic::Attributes::UniqueID::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRCharStringAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeUniqueIDWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                       endpoint:(NSNumber *)endpoint
                                          queue:(dispatch_queue_t)queue
                              completionHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Basic::Attributes::UniqueID::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeCapabilityMinimaWithCompletionHandler:(void (^)(MTRBasicClusterCapabilityMinimaStruct * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    new MTRBasicCapabilityMinimaStructAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Basic::Attributes::CapabilityMinima::TypeInfo;
            auto successFn = Callback<BasicCapabilityMinimaStructAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeCapabilityMinimaWithMinInterval:(NSNumber * _Nonnull)minInterval
                                              maxInterval:(NSNumber * _Nonnull)maxInterval
                                                   params:(MTRSubscribeParams * _Nullable)params
                                  subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                            reportHandler:(void (^)(MTRBasicClusterCapabilityMinimaStruct * _Nullable value,
                                                              NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRBasicCapabilityMinimaStructAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Basic::Attributes::CapabilityMinima::TypeInfo;
            auto successFn = Callback<BasicCapabilityMinimaStructAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRBasicCapabilityMinimaStructAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeCapabilityMinimaWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:(void (^)(MTRBasicClusterCapabilityMinimaStruct * _Nullable value,
                                                            NSError * _Nullable error))completionHandler
{
    new MTRBasicCapabilityMinimaStructAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Basic::Attributes::CapabilityMinima::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<BasicCapabilityMinimaStructAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRBasicGeneratedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Basic::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<BasicGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRBasicGeneratedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Basic::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<BasicGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRBasicGeneratedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBasicGeneratedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Basic::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<BasicGeneratedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRBasicAcceptedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Basic::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<BasicAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRBasicAcceptedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Basic::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<BasicAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRBasicAcceptedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBasicAcceptedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Basic::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<BasicAcceptedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBasicAttributeListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Basic::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<BasicAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRBasicAttributeListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Basic::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<BasicAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRBasicAttributeListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBasicAttributeListListAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Basic::Attributes::AttributeList::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<BasicAttributeListListAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Basic::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Basic::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Basic::Attributes::FeatureMap::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Basic::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Basic::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Basic::Attributes::ClusterRevision::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

@end

@implementation MTRBaseClusterOtaSoftwareUpdateProvider

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = endpoint;
    }
    return self;
}

- (void)queryImageWithParams:(MTROtaSoftwareUpdateProviderClusterQueryImageParams *)params
           completionHandler:(void (^)(MTROtaSoftwareUpdateProviderClusterQueryImageResponseParams * _Nullable data,
                                 NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTROtaSoftwareUpdateProviderClusterQueryImageResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            OtaSoftwareUpdateProvider::Commands::QueryImage::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.vendorId = static_cast<std::remove_reference_t<decltype(request.vendorId)>>(params.vendorId.unsignedShortValue);
            request.productId = params.productId.unsignedShortValue;
            request.softwareVersion = params.softwareVersion.unsignedIntValue;
            {
                using ListType_0 = std::remove_reference_t<decltype(request.protocolsSupported)>;
                using ListMemberType_0 = ListMemberTypeGetter<ListType_0>::Type;
                if (params.protocolsSupported.count != 0) {
                    auto * listHolder_0 = new ListHolder<ListMemberType_0>(params.protocolsSupported.count);
                    if (listHolder_0 == nullptr || listHolder_0->mList == nullptr) {
                        return CHIP_ERROR_INVALID_ARGUMENT;
                    }
                    listFreer.add(listHolder_0);
                    for (size_t i_0 = 0; i_0 < params.protocolsSupported.count; ++i_0) {
                        if (![params.protocolsSupported[i_0] isKindOfClass:[NSNumber class]]) {
                            // Wrong kind of value.
                            return CHIP_ERROR_INVALID_ARGUMENT;
                        }
                        auto element_0 = (NSNumber *) params.protocolsSupported[i_0];
                        listHolder_0->mList[i_0]
                            = static_cast<std::remove_reference_t<decltype(listHolder_0->mList[i_0])>>(element_0.unsignedCharValue);
                    }
                    request.protocolsSupported = ListType_0(listHolder_0->mList, params.protocolsSupported.count);
                } else {
                    request.protocolsSupported = ListType_0();
                }
            }
            if (params.hardwareVersion != nil) {
                auto & definedValue_0 = request.hardwareVersion.Emplace();
                definedValue_0 = params.hardwareVersion.unsignedShortValue;
            }
            if (params.location != nil) {
                auto & definedValue_0 = request.location.Emplace();
                definedValue_0 = [self asCharSpan:params.location];
            }
            if (params.requestorCanConsent != nil) {
                auto & definedValue_0 = request.requestorCanConsent.Emplace();
                definedValue_0 = params.requestorCanConsent.boolValue;
            }
            if (params.metadataForProvider != nil) {
                auto & definedValue_0 = request.metadataForProvider.Emplace();
                definedValue_0 = [self asByteSpan:params.metadataForProvider];
            }

            auto successFn = Callback<OtaSoftwareUpdateProviderClusterQueryImageResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OtaSoftwareUpdateProviderCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)applyUpdateRequestWithParams:(MTROtaSoftwareUpdateProviderClusterApplyUpdateRequestParams *)params
                   completionHandler:(void (^)(MTROtaSoftwareUpdateProviderClusterApplyUpdateResponseParams * _Nullable data,
                                         NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTROtaSoftwareUpdateProviderClusterApplyUpdateResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            OtaSoftwareUpdateProvider::Commands::ApplyUpdateRequest::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.updateToken = [self asByteSpan:params.updateToken];
            request.newVersion = params.newVersion.unsignedIntValue;

            auto successFn = Callback<OtaSoftwareUpdateProviderClusterApplyUpdateResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OtaSoftwareUpdateProviderCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)notifyUpdateAppliedWithParams:(MTROtaSoftwareUpdateProviderClusterNotifyUpdateAppliedParams *)params
                    completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            OtaSoftwareUpdateProvider::Commands::NotifyUpdateApplied::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.updateToken = [self asByteSpan:params.updateToken];
            request.softwareVersion = params.softwareVersion.unsignedIntValue;

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OtaSoftwareUpdateProviderCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTROtaSoftwareUpdateProviderGeneratedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device,
        completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = OtaSoftwareUpdateProvider::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<OtaSoftwareUpdateProviderGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OtaSoftwareUpdateProviderCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTROtaSoftwareUpdateProviderGeneratedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = OtaSoftwareUpdateProvider::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<OtaSoftwareUpdateProviderGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::OtaSoftwareUpdateProviderCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTROtaSoftwareUpdateProviderGeneratedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished,
                nil, params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTROtaSoftwareUpdateProviderGeneratedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OtaSoftwareUpdateProvider::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn
                    = Callback<OtaSoftwareUpdateProviderGeneratedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTROtaSoftwareUpdateProviderAcceptedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device,
        completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = OtaSoftwareUpdateProvider::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<OtaSoftwareUpdateProviderAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OtaSoftwareUpdateProviderCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTROtaSoftwareUpdateProviderAcceptedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = OtaSoftwareUpdateProvider::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<OtaSoftwareUpdateProviderAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::OtaSoftwareUpdateProviderCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTROtaSoftwareUpdateProviderAcceptedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished,
                nil, params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTROtaSoftwareUpdateProviderAcceptedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OtaSoftwareUpdateProvider::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn
                    = Callback<OtaSoftwareUpdateProviderAcceptedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTROtaSoftwareUpdateProviderAttributeListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = OtaSoftwareUpdateProvider::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<OtaSoftwareUpdateProviderAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OtaSoftwareUpdateProviderCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTROtaSoftwareUpdateProviderAttributeListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = OtaSoftwareUpdateProvider::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<OtaSoftwareUpdateProviderAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::OtaSoftwareUpdateProviderCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTROtaSoftwareUpdateProviderAttributeListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTROtaSoftwareUpdateProviderAttributeListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OtaSoftwareUpdateProvider::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<OtaSoftwareUpdateProviderAttributeListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = OtaSoftwareUpdateProvider::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OtaSoftwareUpdateProviderCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = OtaSoftwareUpdateProvider::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::OtaSoftwareUpdateProviderCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = OtaSoftwareUpdateProvider::Attributes::FeatureMap::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = OtaSoftwareUpdateProvider::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OtaSoftwareUpdateProviderCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = OtaSoftwareUpdateProvider::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::OtaSoftwareUpdateProviderCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = OtaSoftwareUpdateProvider::Attributes::ClusterRevision::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

@end

@implementation MTRBaseClusterOtaSoftwareUpdateRequestor

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = endpoint;
    }
    return self;
}

- (void)announceOtaProviderWithParams:(MTROtaSoftwareUpdateRequestorClusterAnnounceOtaProviderParams *)params
                    completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            OtaSoftwareUpdateRequestor::Commands::AnnounceOtaProvider::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.providerNodeId = params.providerNodeId.unsignedLongLongValue;
            request.vendorId = static_cast<std::remove_reference_t<decltype(request.vendorId)>>(params.vendorId.unsignedShortValue);
            request.announcementReason = static_cast<std::remove_reference_t<decltype(request.announcementReason)>>(
                params.announcementReason.unsignedCharValue);
            if (params.metadataForNode != nil) {
                auto & definedValue_0 = request.metadataForNode.Emplace();
                definedValue_0 = [self asByteSpan:params.metadataForNode];
            }
            request.endpoint = params.endpoint.unsignedShortValue;

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OtaSoftwareUpdateRequestorCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)readAttributeDefaultOtaProvidersWithParams:(MTRReadParams * _Nullable)params
                                 completionHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{ // Make a copy of params before we go async.
    params = [params copy];
    new MTROtaSoftwareUpdateRequestorDefaultOtaProvidersListAttributeCallbackBridge(self.callbackQueue, self.device,
        completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = OtaSoftwareUpdateRequestor::Attributes::DefaultOtaProviders::TypeInfo;
            auto successFn = Callback<OtaSoftwareUpdateRequestorDefaultOtaProvidersListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OtaSoftwareUpdateRequestorCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue]);
        });
}

- (void)writeAttributeDefaultOtaProvidersWithValue:(NSArray * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeDefaultOtaProvidersWithValue:(NSArray * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeDefaultOtaProvidersWithValue:(NSArray * _Nonnull)value
                                            params:(MTRWriteParams * _Nullable)params
                                 completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = OtaSoftwareUpdateRequestor::Attributes::DefaultOtaProviders::TypeInfo;
            TypeInfo::Type cppValue;
            {
                using ListType_0 = std::remove_reference_t<decltype(cppValue)>;
                using ListMemberType_0 = ListMemberTypeGetter<ListType_0>::Type;
                if (value.count != 0) {
                    auto * listHolder_0 = new ListHolder<ListMemberType_0>(value.count);
                    if (listHolder_0 == nullptr || listHolder_0->mList == nullptr) {
                        return CHIP_ERROR_INVALID_ARGUMENT;
                    }
                    listFreer.add(listHolder_0);
                    for (size_t i_0 = 0; i_0 < value.count; ++i_0) {
                        if (![value[i_0] isKindOfClass:[MTROtaSoftwareUpdateRequestorClusterProviderLocation class]]) {
                            // Wrong kind of value.
                            return CHIP_ERROR_INVALID_ARGUMENT;
                        }
                        auto element_0 = (MTROtaSoftwareUpdateRequestorClusterProviderLocation *) value[i_0];
                        listHolder_0->mList[i_0].providerNodeID = element_0.providerNodeID.unsignedLongLongValue;
                        listHolder_0->mList[i_0].endpoint = element_0.endpoint.unsignedShortValue;
                        listHolder_0->mList[i_0].fabricIndex = element_0.fabricIndex.unsignedCharValue;
                    }
                    cppValue = ListType_0(listHolder_0->mList, value.count);
                } else {
                    cppValue = ListType_0();
                }
            }
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::OtaSoftwareUpdateRequestorCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeDefaultOtaProvidersWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTROtaSoftwareUpdateRequestorDefaultOtaProvidersListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = OtaSoftwareUpdateRequestor::Attributes::DefaultOtaProviders::TypeInfo;
            auto successFn = Callback<OtaSoftwareUpdateRequestorDefaultOtaProvidersListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::OtaSoftwareUpdateRequestorCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTROtaSoftwareUpdateRequestorDefaultOtaProvidersListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished,
                nil, params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeDefaultOtaProvidersWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTROtaSoftwareUpdateRequestorDefaultOtaProvidersListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OtaSoftwareUpdateRequestor::Attributes::DefaultOtaProviders::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn
                    = Callback<OtaSoftwareUpdateRequestorDefaultOtaProvidersListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeUpdatePossibleWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    new MTRBooleanAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = OtaSoftwareUpdateRequestor::Attributes::UpdatePossible::TypeInfo;
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OtaSoftwareUpdateRequestorCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeUpdatePossibleWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRBooleanAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = OtaSoftwareUpdateRequestor::Attributes::UpdatePossible::TypeInfo;
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::OtaSoftwareUpdateRequestorCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRBooleanAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeUpdatePossibleWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBooleanAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = OtaSoftwareUpdateRequestor::Attributes::UpdatePossible::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeUpdateStateWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTROtaSoftwareUpdateRequestorClusterOTAUpdateStateEnumAttributeCallbackBridge(self.callbackQueue, self.device,
        completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = OtaSoftwareUpdateRequestor::Attributes::UpdateState::TypeInfo;
            auto successFn
                = Callback<OtaSoftwareUpdateRequestorClusterOTAUpdateStateEnumAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OtaSoftwareUpdateRequestorCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeUpdateStateWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTROtaSoftwareUpdateRequestorClusterOTAUpdateStateEnumAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = OtaSoftwareUpdateRequestor::Attributes::UpdateState::TypeInfo;
            auto successFn
                = Callback<OtaSoftwareUpdateRequestorClusterOTAUpdateStateEnumAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::OtaSoftwareUpdateRequestorCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTROtaSoftwareUpdateRequestorClusterOTAUpdateStateEnumAttributeCallbackSubscriptionBridge::
                    OnSubscriptionEstablished,
                nil, params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeUpdateStateWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTROtaSoftwareUpdateRequestorClusterOTAUpdateStateEnumAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OtaSoftwareUpdateRequestor::Attributes::UpdateState::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn
                    = Callback<OtaSoftwareUpdateRequestorClusterOTAUpdateStateEnumAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeUpdateStateProgressWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = OtaSoftwareUpdateRequestor::Attributes::UpdateStateProgress::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OtaSoftwareUpdateRequestorCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeUpdateStateProgressWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = OtaSoftwareUpdateRequestor::Attributes::UpdateStateProgress::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::OtaSoftwareUpdateRequestorCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeUpdateStateProgressWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = OtaSoftwareUpdateRequestor::Attributes::UpdateStateProgress::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTROtaSoftwareUpdateRequestorGeneratedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device,
        completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = OtaSoftwareUpdateRequestor::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<OtaSoftwareUpdateRequestorGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OtaSoftwareUpdateRequestorCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTROtaSoftwareUpdateRequestorGeneratedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = OtaSoftwareUpdateRequestor::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<OtaSoftwareUpdateRequestorGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::OtaSoftwareUpdateRequestorCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTROtaSoftwareUpdateRequestorGeneratedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished,
                nil, params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTROtaSoftwareUpdateRequestorGeneratedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OtaSoftwareUpdateRequestor::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn
                    = Callback<OtaSoftwareUpdateRequestorGeneratedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTROtaSoftwareUpdateRequestorAcceptedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device,
        completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = OtaSoftwareUpdateRequestor::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<OtaSoftwareUpdateRequestorAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OtaSoftwareUpdateRequestorCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTROtaSoftwareUpdateRequestorAcceptedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = OtaSoftwareUpdateRequestor::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<OtaSoftwareUpdateRequestorAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::OtaSoftwareUpdateRequestorCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTROtaSoftwareUpdateRequestorAcceptedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished,
                nil, params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTROtaSoftwareUpdateRequestorAcceptedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OtaSoftwareUpdateRequestor::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn
                    = Callback<OtaSoftwareUpdateRequestorAcceptedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTROtaSoftwareUpdateRequestorAttributeListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = OtaSoftwareUpdateRequestor::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<OtaSoftwareUpdateRequestorAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OtaSoftwareUpdateRequestorCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTROtaSoftwareUpdateRequestorAttributeListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = OtaSoftwareUpdateRequestor::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<OtaSoftwareUpdateRequestorAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::OtaSoftwareUpdateRequestorCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTROtaSoftwareUpdateRequestorAttributeListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTROtaSoftwareUpdateRequestorAttributeListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OtaSoftwareUpdateRequestor::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<OtaSoftwareUpdateRequestorAttributeListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = OtaSoftwareUpdateRequestor::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OtaSoftwareUpdateRequestorCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = OtaSoftwareUpdateRequestor::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::OtaSoftwareUpdateRequestorCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = OtaSoftwareUpdateRequestor::Attributes::FeatureMap::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = OtaSoftwareUpdateRequestor::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OtaSoftwareUpdateRequestorCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = OtaSoftwareUpdateRequestor::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::OtaSoftwareUpdateRequestorCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = OtaSoftwareUpdateRequestor::Attributes::ClusterRevision::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

@end

@implementation MTRBaseClusterLocalizationConfiguration

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = endpoint;
    }
    return self;
}

- (void)readAttributeActiveLocaleWithCompletionHandler:(void (^)(
                                                           NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = LocalizationConfiguration::Attributes::ActiveLocale::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::LocalizationConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeActiveLocaleWithValue:(NSString * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeActiveLocaleWithValue:(NSString * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeActiveLocaleWithValue:(NSString * _Nonnull)value
                                     params:(MTRWriteParams * _Nullable)params
                          completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = LocalizationConfiguration::Attributes::ActiveLocale::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = [self asCharSpan:value];
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::LocalizationConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeActiveLocaleWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRCharStringAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = LocalizationConfiguration::Attributes::ActiveLocale::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::LocalizationConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRCharStringAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeActiveLocaleWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = LocalizationConfiguration::Attributes::ActiveLocale::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeSupportedLocalesWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    new MTRLocalizationConfigurationSupportedLocalesListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = LocalizationConfiguration::Attributes::SupportedLocales::TypeInfo;
            auto successFn = Callback<LocalizationConfigurationSupportedLocalesListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::LocalizationConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeSupportedLocalesWithMinInterval:(NSNumber * _Nonnull)minInterval
                                              maxInterval:(NSNumber * _Nonnull)maxInterval
                                                   params:(MTRSubscribeParams * _Nullable)params
                                  subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                            reportHandler:
                                                (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRLocalizationConfigurationSupportedLocalesListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = LocalizationConfiguration::Attributes::SupportedLocales::TypeInfo;
            auto successFn = Callback<LocalizationConfigurationSupportedLocalesListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::LocalizationConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRLocalizationConfigurationSupportedLocalesListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeSupportedLocalesWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRLocalizationConfigurationSupportedLocalesListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = LocalizationConfiguration::Attributes::SupportedLocales::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<LocalizationConfigurationSupportedLocalesListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRLocalizationConfigurationGeneratedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device,
        completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = LocalizationConfiguration::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<LocalizationConfigurationGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::LocalizationConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRLocalizationConfigurationGeneratedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = LocalizationConfiguration::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<LocalizationConfigurationGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::LocalizationConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRLocalizationConfigurationGeneratedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished,
                nil, params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRLocalizationConfigurationGeneratedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = LocalizationConfiguration::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn
                    = Callback<LocalizationConfigurationGeneratedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRLocalizationConfigurationAcceptedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device,
        completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = LocalizationConfiguration::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<LocalizationConfigurationAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::LocalizationConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRLocalizationConfigurationAcceptedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = LocalizationConfiguration::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<LocalizationConfigurationAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::LocalizationConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRLocalizationConfigurationAcceptedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished,
                nil, params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRLocalizationConfigurationAcceptedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = LocalizationConfiguration::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn
                    = Callback<LocalizationConfigurationAcceptedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRLocalizationConfigurationAttributeListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = LocalizationConfiguration::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<LocalizationConfigurationAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::LocalizationConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRLocalizationConfigurationAttributeListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = LocalizationConfiguration::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<LocalizationConfigurationAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::LocalizationConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRLocalizationConfigurationAttributeListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRLocalizationConfigurationAttributeListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = LocalizationConfiguration::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<LocalizationConfigurationAttributeListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = LocalizationConfiguration::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::LocalizationConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = LocalizationConfiguration::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::LocalizationConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = LocalizationConfiguration::Attributes::FeatureMap::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = LocalizationConfiguration::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::LocalizationConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = LocalizationConfiguration::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::LocalizationConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = LocalizationConfiguration::Attributes::ClusterRevision::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

@end

@implementation MTRBaseClusterTimeFormatLocalization

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = endpoint;
    }
    return self;
}

- (void)readAttributeHourFormatWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRTimeFormatLocalizationClusterHourFormatAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TimeFormatLocalization::Attributes::HourFormat::TypeInfo;
            auto successFn = Callback<TimeFormatLocalizationClusterHourFormatAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TimeFormatLocalizationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeHourFormatWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeHourFormatWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeHourFormatWithValue:(NSNumber * _Nonnull)value
                                   params:(MTRWriteParams * _Nullable)params
                        completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TimeFormatLocalization::Attributes::HourFormat::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = static_cast<std::remove_reference_t<decltype(cppValue)>>(value.unsignedCharValue);
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TimeFormatLocalizationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeHourFormatWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRTimeFormatLocalizationClusterHourFormatAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TimeFormatLocalization::Attributes::HourFormat::TypeInfo;
            auto successFn = Callback<TimeFormatLocalizationClusterHourFormatAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TimeFormatLocalizationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRTimeFormatLocalizationClusterHourFormatAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeHourFormatWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRTimeFormatLocalizationClusterHourFormatAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TimeFormatLocalization::Attributes::HourFormat::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<TimeFormatLocalizationClusterHourFormatAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeActiveCalendarTypeWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                 NSError * _Nullable error))completionHandler
{
    new MTRTimeFormatLocalizationClusterCalendarTypeAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TimeFormatLocalization::Attributes::ActiveCalendarType::TypeInfo;
            auto successFn = Callback<TimeFormatLocalizationClusterCalendarTypeAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TimeFormatLocalizationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeActiveCalendarTypeWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeActiveCalendarTypeWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeActiveCalendarTypeWithValue:(NSNumber * _Nonnull)value
                                           params:(MTRWriteParams * _Nullable)params
                                completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TimeFormatLocalization::Attributes::ActiveCalendarType::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = static_cast<std::remove_reference_t<decltype(cppValue)>>(value.unsignedCharValue);
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TimeFormatLocalizationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeActiveCalendarTypeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                maxInterval:(NSNumber * _Nonnull)maxInterval
                                                     params:(MTRSubscribeParams * _Nullable)params
                                    subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                              reportHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRTimeFormatLocalizationClusterCalendarTypeAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TimeFormatLocalization::Attributes::ActiveCalendarType::TypeInfo;
            auto successFn = Callback<TimeFormatLocalizationClusterCalendarTypeAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TimeFormatLocalizationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRTimeFormatLocalizationClusterCalendarTypeAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeActiveCalendarTypeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                        completionHandler:
                                            (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRTimeFormatLocalizationClusterCalendarTypeAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TimeFormatLocalization::Attributes::ActiveCalendarType::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<TimeFormatLocalizationClusterCalendarTypeAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeSupportedCalendarTypesWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                     NSError * _Nullable error))completionHandler
{
    new MTRTimeFormatLocalizationSupportedCalendarTypesListAttributeCallbackBridge(self.callbackQueue, self.device,
        completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TimeFormatLocalization::Attributes::SupportedCalendarTypes::TypeInfo;
            auto successFn = Callback<TimeFormatLocalizationSupportedCalendarTypesListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TimeFormatLocalizationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeSupportedCalendarTypesWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                                         params:(MTRSubscribeParams * _Nullable)params
                                        subscriptionEstablished:
                                            (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                  reportHandler:
                                                      (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRTimeFormatLocalizationSupportedCalendarTypesListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TimeFormatLocalization::Attributes::SupportedCalendarTypes::TypeInfo;
            auto successFn = Callback<TimeFormatLocalizationSupportedCalendarTypesListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TimeFormatLocalizationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRTimeFormatLocalizationSupportedCalendarTypesListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished,
                nil, params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeSupportedCalendarTypesWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                            completionHandler:
                                                (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRTimeFormatLocalizationSupportedCalendarTypesListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TimeFormatLocalization::Attributes::SupportedCalendarTypes::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn
                    = Callback<TimeFormatLocalizationSupportedCalendarTypesListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRTimeFormatLocalizationGeneratedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TimeFormatLocalization::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<TimeFormatLocalizationGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TimeFormatLocalizationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRTimeFormatLocalizationGeneratedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TimeFormatLocalization::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<TimeFormatLocalizationGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TimeFormatLocalizationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRTimeFormatLocalizationGeneratedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished,
                nil, params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRTimeFormatLocalizationGeneratedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TimeFormatLocalization::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<TimeFormatLocalizationGeneratedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRTimeFormatLocalizationAcceptedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TimeFormatLocalization::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<TimeFormatLocalizationAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TimeFormatLocalizationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRTimeFormatLocalizationAcceptedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TimeFormatLocalization::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<TimeFormatLocalizationAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TimeFormatLocalizationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRTimeFormatLocalizationAcceptedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRTimeFormatLocalizationAcceptedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TimeFormatLocalization::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<TimeFormatLocalizationAcceptedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRTimeFormatLocalizationAttributeListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TimeFormatLocalization::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<TimeFormatLocalizationAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TimeFormatLocalizationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRTimeFormatLocalizationAttributeListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TimeFormatLocalization::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<TimeFormatLocalizationAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TimeFormatLocalizationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRTimeFormatLocalizationAttributeListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRTimeFormatLocalizationAttributeListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TimeFormatLocalization::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<TimeFormatLocalizationAttributeListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TimeFormatLocalization::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TimeFormatLocalizationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TimeFormatLocalization::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TimeFormatLocalizationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TimeFormatLocalization::Attributes::FeatureMap::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TimeFormatLocalization::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TimeFormatLocalizationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TimeFormatLocalization::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TimeFormatLocalizationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TimeFormatLocalization::Attributes::ClusterRevision::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

@end

@implementation MTRBaseClusterUnitLocalization

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = endpoint;
    }
    return self;
}

- (void)readAttributeTemperatureUnitWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRUnitLocalizationClusterTempUnitAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = UnitLocalization::Attributes::TemperatureUnit::TypeInfo;
            auto successFn = Callback<UnitLocalizationClusterTempUnitAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::UnitLocalizationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeTemperatureUnitWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeTemperatureUnitWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeTemperatureUnitWithValue:(NSNumber * _Nonnull)value
                                        params:(MTRWriteParams * _Nullable)params
                             completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UnitLocalization::Attributes::TemperatureUnit::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = static_cast<std::remove_reference_t<decltype(cppValue)>>(value.unsignedCharValue);
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::UnitLocalizationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeTemperatureUnitWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRUnitLocalizationClusterTempUnitAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = UnitLocalization::Attributes::TemperatureUnit::TypeInfo;
            auto successFn = Callback<UnitLocalizationClusterTempUnitAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::UnitLocalizationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRUnitLocalizationClusterTempUnitAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeTemperatureUnitWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRUnitLocalizationClusterTempUnitAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitLocalization::Attributes::TemperatureUnit::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<UnitLocalizationClusterTempUnitAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRUnitLocalizationGeneratedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = UnitLocalization::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<UnitLocalizationGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::UnitLocalizationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRUnitLocalizationGeneratedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = UnitLocalization::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<UnitLocalizationGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::UnitLocalizationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRUnitLocalizationGeneratedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRUnitLocalizationGeneratedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitLocalization::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<UnitLocalizationGeneratedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRUnitLocalizationAcceptedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = UnitLocalization::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<UnitLocalizationAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::UnitLocalizationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRUnitLocalizationAcceptedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = UnitLocalization::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<UnitLocalizationAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::UnitLocalizationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRUnitLocalizationAcceptedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRUnitLocalizationAcceptedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitLocalization::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<UnitLocalizationAcceptedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRUnitLocalizationAttributeListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = UnitLocalization::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<UnitLocalizationAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::UnitLocalizationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRUnitLocalizationAttributeListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = UnitLocalization::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<UnitLocalizationAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::UnitLocalizationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRUnitLocalizationAttributeListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRUnitLocalizationAttributeListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UnitLocalization::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<UnitLocalizationAttributeListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = UnitLocalization::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::UnitLocalizationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = UnitLocalization::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::UnitLocalizationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = UnitLocalization::Attributes::FeatureMap::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = UnitLocalization::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::UnitLocalizationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = UnitLocalization::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::UnitLocalizationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = UnitLocalization::Attributes::ClusterRevision::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

@end

@implementation MTRBaseClusterPowerSourceConfiguration

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = endpoint;
    }
    return self;
}

- (void)readAttributeSourcesWithCompletionHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRPowerSourceConfigurationSourcesListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PowerSourceConfiguration::Attributes::Sources::TypeInfo;
            auto successFn = Callback<PowerSourceConfigurationSourcesListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PowerSourceConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeSourcesWithMinInterval:(NSNumber * _Nonnull)minInterval
                                     maxInterval:(NSNumber * _Nonnull)maxInterval
                                          params:(MTRSubscribeParams * _Nullable)params
                         subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                   reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRPowerSourceConfigurationSourcesListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PowerSourceConfiguration::Attributes::Sources::TypeInfo;
            auto successFn = Callback<PowerSourceConfigurationSourcesListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PowerSourceConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRPowerSourceConfigurationSourcesListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeSourcesWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                      endpoint:(NSNumber *)endpoint
                                         queue:(dispatch_queue_t)queue
                             completionHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRPowerSourceConfigurationSourcesListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PowerSourceConfiguration::Attributes::Sources::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<PowerSourceConfigurationSourcesListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRPowerSourceConfigurationGeneratedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device,
        completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PowerSourceConfiguration::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<PowerSourceConfigurationGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PowerSourceConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRPowerSourceConfigurationGeneratedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PowerSourceConfiguration::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<PowerSourceConfigurationGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PowerSourceConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRPowerSourceConfigurationGeneratedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished,
                nil, params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRPowerSourceConfigurationGeneratedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PowerSourceConfiguration::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn
                    = Callback<PowerSourceConfigurationGeneratedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRPowerSourceConfigurationAcceptedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device,
        completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PowerSourceConfiguration::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<PowerSourceConfigurationAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PowerSourceConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRPowerSourceConfigurationAcceptedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PowerSourceConfiguration::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<PowerSourceConfigurationAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PowerSourceConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRPowerSourceConfigurationAcceptedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished,
                nil, params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRPowerSourceConfigurationAcceptedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PowerSourceConfiguration::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn
                    = Callback<PowerSourceConfigurationAcceptedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRPowerSourceConfigurationAttributeListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PowerSourceConfiguration::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<PowerSourceConfigurationAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PowerSourceConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRPowerSourceConfigurationAttributeListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PowerSourceConfiguration::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<PowerSourceConfigurationAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PowerSourceConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRPowerSourceConfigurationAttributeListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRPowerSourceConfigurationAttributeListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PowerSourceConfiguration::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<PowerSourceConfigurationAttributeListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PowerSourceConfiguration::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PowerSourceConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PowerSourceConfiguration::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PowerSourceConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = PowerSourceConfiguration::Attributes::FeatureMap::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PowerSourceConfiguration::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PowerSourceConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PowerSourceConfiguration::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PowerSourceConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = PowerSourceConfiguration::Attributes::ClusterRevision::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

@end

@implementation MTRBaseClusterPowerSource

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = endpoint;
    }
    return self;
}

- (void)readAttributeStatusWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRPowerSourceClusterPowerSourceStatusAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PowerSource::Attributes::Status::TypeInfo;
            auto successFn = Callback<PowerSourceClusterPowerSourceStatusAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PowerSourceCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeStatusWithMinInterval:(NSNumber * _Nonnull)minInterval
                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                         params:(MTRSubscribeParams * _Nullable)params
                        subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRPowerSourceClusterPowerSourceStatusAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PowerSource::Attributes::Status::TypeInfo;
            auto successFn = Callback<PowerSourceClusterPowerSourceStatusAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PowerSourceCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRPowerSourceClusterPowerSourceStatusAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeStatusWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                     endpoint:(NSNumber *)endpoint
                                        queue:(dispatch_queue_t)queue
                            completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRPowerSourceClusterPowerSourceStatusAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PowerSource::Attributes::Status::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<PowerSourceClusterPowerSourceStatusAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeOrderWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PowerSource::Attributes::Order::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PowerSourceCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeOrderWithMinInterval:(NSNumber * _Nonnull)minInterval
                                   maxInterval:(NSNumber * _Nonnull)maxInterval
                                        params:(MTRSubscribeParams * _Nullable)params
                       subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PowerSource::Attributes::Order::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PowerSourceCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeOrderWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                    endpoint:(NSNumber *)endpoint
                                       queue:(dispatch_queue_t)queue
                           completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = PowerSource::Attributes::Order::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeDescriptionWithCompletionHandler:(void (^)(
                                                          NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PowerSource::Attributes::Description::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PowerSourceCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeDescriptionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRCharStringAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PowerSource::Attributes::Description::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PowerSourceCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRCharStringAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeDescriptionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = PowerSource::Attributes::Description::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeWiredAssessedInputVoltageWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))completionHandler
{
    new MTRNullableInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PowerSource::Attributes::WiredAssessedInputVoltage::TypeInfo;
            auto successFn = Callback<NullableInt32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PowerSourceCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeWiredAssessedInputVoltageWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                                            params:(MTRSubscribeParams * _Nullable)params
                                           subscriptionEstablished:
                                               (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                     reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PowerSource::Attributes::WiredAssessedInputVoltage::TypeInfo;
            auto successFn = Callback<NullableInt32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PowerSourceCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeWiredAssessedInputVoltageWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                        endpoint:(NSNumber *)endpoint
                                                           queue:(dispatch_queue_t)queue
                                               completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completionHandler
{
    new MTRNullableInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = PowerSource::Attributes::WiredAssessedInputVoltage::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeWiredAssessedInputFrequencyWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                          NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PowerSource::Attributes::WiredAssessedInputFrequency::TypeInfo;
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PowerSourceCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeWiredAssessedInputFrequencyWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                                              params:(MTRSubscribeParams * _Nullable)params
                                             subscriptionEstablished:
                                                 (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                       reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PowerSource::Attributes::WiredAssessedInputFrequency::TypeInfo;
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PowerSourceCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeWiredAssessedInputFrequencyWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                          endpoint:(NSNumber *)endpoint
                                                             queue:(dispatch_queue_t)queue
                                                 completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = PowerSource::Attributes::WiredAssessedInputFrequency::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeWiredCurrentTypeWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    new MTRPowerSourceClusterWiredCurrentTypeAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PowerSource::Attributes::WiredCurrentType::TypeInfo;
            auto successFn = Callback<PowerSourceClusterWiredCurrentTypeAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PowerSourceCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeWiredCurrentTypeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                              maxInterval:(NSNumber * _Nonnull)maxInterval
                                                   params:(MTRSubscribeParams * _Nullable)params
                                  subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                            reportHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRPowerSourceClusterWiredCurrentTypeAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PowerSource::Attributes::WiredCurrentType::TypeInfo;
            auto successFn = Callback<PowerSourceClusterWiredCurrentTypeAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PowerSourceCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRPowerSourceClusterWiredCurrentTypeAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeWiredCurrentTypeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRPowerSourceClusterWiredCurrentTypeAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PowerSource::Attributes::WiredCurrentType::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<PowerSourceClusterWiredCurrentTypeAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeWiredAssessedCurrentWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRNullableInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PowerSource::Attributes::WiredAssessedCurrent::TypeInfo;
            auto successFn = Callback<NullableInt32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PowerSourceCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeWiredAssessedCurrentWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PowerSource::Attributes::WiredAssessedCurrent::TypeInfo;
            auto successFn = Callback<NullableInt32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PowerSourceCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeWiredAssessedCurrentWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = PowerSource::Attributes::WiredAssessedCurrent::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeWiredNominalVoltageWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PowerSource::Attributes::WiredNominalVoltage::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PowerSourceCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeWiredNominalVoltageWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PowerSource::Attributes::WiredNominalVoltage::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PowerSourceCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeWiredNominalVoltageWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = PowerSource::Attributes::WiredNominalVoltage::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeWiredMaximumCurrentWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PowerSource::Attributes::WiredMaximumCurrent::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PowerSourceCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeWiredMaximumCurrentWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PowerSource::Attributes::WiredMaximumCurrent::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PowerSourceCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeWiredMaximumCurrentWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = PowerSource::Attributes::WiredMaximumCurrent::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeWiredPresentWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBooleanAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PowerSource::Attributes::WiredPresent::TypeInfo;
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PowerSourceCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeWiredPresentWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRBooleanAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PowerSource::Attributes::WiredPresent::TypeInfo;
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PowerSourceCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRBooleanAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeWiredPresentWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBooleanAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = PowerSource::Attributes::WiredPresent::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeActiveWiredFaultsWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    new MTRPowerSourceActiveWiredFaultsListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PowerSource::Attributes::ActiveWiredFaults::TypeInfo;
            auto successFn = Callback<PowerSourceActiveWiredFaultsListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PowerSourceCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeActiveWiredFaultsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRPowerSourceActiveWiredFaultsListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PowerSource::Attributes::ActiveWiredFaults::TypeInfo;
            auto successFn = Callback<PowerSourceActiveWiredFaultsListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PowerSourceCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRPowerSourceActiveWiredFaultsListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeActiveWiredFaultsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRPowerSourceActiveWiredFaultsListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PowerSource::Attributes::ActiveWiredFaults::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<PowerSourceActiveWiredFaultsListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeBatVoltageWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PowerSource::Attributes::BatVoltage::TypeInfo;
            auto successFn = Callback<NullableInt32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PowerSourceCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeBatVoltageWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PowerSource::Attributes::BatVoltage::TypeInfo;
            auto successFn = Callback<NullableInt32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PowerSourceCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeBatVoltageWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = PowerSource::Attributes::BatVoltage::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeBatPercentRemainingWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PowerSource::Attributes::BatPercentRemaining::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PowerSourceCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeBatPercentRemainingWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PowerSource::Attributes::BatPercentRemaining::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PowerSourceCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeBatPercentRemainingWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = PowerSource::Attributes::BatPercentRemaining::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeBatTimeRemainingWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    new MTRNullableInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PowerSource::Attributes::BatTimeRemaining::TypeInfo;
            auto successFn = Callback<NullableInt32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PowerSourceCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeBatTimeRemainingWithMinInterval:(NSNumber * _Nonnull)minInterval
                                              maxInterval:(NSNumber * _Nonnull)maxInterval
                                                   params:(MTRSubscribeParams * _Nullable)params
                                  subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                            reportHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PowerSource::Attributes::BatTimeRemaining::TypeInfo;
            auto successFn = Callback<NullableInt32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PowerSourceCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeBatTimeRemainingWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = PowerSource::Attributes::BatTimeRemaining::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeBatChargeLevelWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    new MTRPowerSourceClusterBatChargeLevelAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PowerSource::Attributes::BatChargeLevel::TypeInfo;
            auto successFn = Callback<PowerSourceClusterBatChargeLevelAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PowerSourceCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeBatChargeLevelWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRPowerSourceClusterBatChargeLevelAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PowerSource::Attributes::BatChargeLevel::TypeInfo;
            auto successFn = Callback<PowerSourceClusterBatChargeLevelAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PowerSourceCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRPowerSourceClusterBatChargeLevelAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeBatChargeLevelWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRPowerSourceClusterBatChargeLevelAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PowerSource::Attributes::BatChargeLevel::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<PowerSourceClusterBatChargeLevelAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeBatReplacementNeededWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRBooleanAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PowerSource::Attributes::BatReplacementNeeded::TypeInfo;
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PowerSourceCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeBatReplacementNeededWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRBooleanAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PowerSource::Attributes::BatReplacementNeeded::TypeInfo;
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PowerSourceCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRBooleanAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeBatReplacementNeededWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBooleanAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = PowerSource::Attributes::BatReplacementNeeded::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeBatReplaceabilityWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    new MTRPowerSourceClusterBatReplaceabilityAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PowerSource::Attributes::BatReplaceability::TypeInfo;
            auto successFn = Callback<PowerSourceClusterBatReplaceabilityAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PowerSourceCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeBatReplaceabilityWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRPowerSourceClusterBatReplaceabilityAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PowerSource::Attributes::BatReplaceability::TypeInfo;
            auto successFn = Callback<PowerSourceClusterBatReplaceabilityAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PowerSourceCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRPowerSourceClusterBatReplaceabilityAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeBatReplaceabilityWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRPowerSourceClusterBatReplaceabilityAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PowerSource::Attributes::BatReplaceability::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<PowerSourceClusterBatReplaceabilityAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeBatPresentWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBooleanAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PowerSource::Attributes::BatPresent::TypeInfo;
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PowerSourceCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeBatPresentWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRBooleanAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PowerSource::Attributes::BatPresent::TypeInfo;
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PowerSourceCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRBooleanAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeBatPresentWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBooleanAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = PowerSource::Attributes::BatPresent::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeActiveBatFaultsWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRPowerSourceActiveBatFaultsListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PowerSource::Attributes::ActiveBatFaults::TypeInfo;
            auto successFn = Callback<PowerSourceActiveBatFaultsListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PowerSourceCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeActiveBatFaultsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRPowerSourceActiveBatFaultsListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PowerSource::Attributes::ActiveBatFaults::TypeInfo;
            auto successFn = Callback<PowerSourceActiveBatFaultsListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PowerSourceCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRPowerSourceActiveBatFaultsListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeActiveBatFaultsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRPowerSourceActiveBatFaultsListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PowerSource::Attributes::ActiveBatFaults::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<PowerSourceActiveBatFaultsListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeBatReplacementDescriptionWithCompletionHandler:(void (^)(NSString * _Nullable value,
                                                                        NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PowerSource::Attributes::BatReplacementDescription::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PowerSourceCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeBatReplacementDescriptionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                                            params:(MTRSubscribeParams * _Nullable)params
                                           subscriptionEstablished:
                                               (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                     reportHandler:(void (^)(NSString * _Nullable value,
                                                                       NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRCharStringAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PowerSource::Attributes::BatReplacementDescription::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PowerSourceCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRCharStringAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeBatReplacementDescriptionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                        endpoint:(NSNumber *)endpoint
                                                           queue:(dispatch_queue_t)queue
                                               completionHandler:(void (^)(NSString * _Nullable value,
                                                                     NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = PowerSource::Attributes::BatReplacementDescription::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeBatCommonDesignationWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PowerSource::Attributes::BatCommonDesignation::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PowerSourceCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeBatCommonDesignationWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PowerSource::Attributes::BatCommonDesignation::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PowerSourceCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeBatCommonDesignationWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = PowerSource::Attributes::BatCommonDesignation::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeBatANSIDesignationWithCompletionHandler:(void (^)(NSString * _Nullable value,
                                                                 NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PowerSource::Attributes::BatANSIDesignation::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PowerSourceCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeBatANSIDesignationWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                maxInterval:(NSNumber * _Nonnull)maxInterval
                                                     params:(MTRSubscribeParams * _Nullable)params
                                    subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                              reportHandler:
                                                  (void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRCharStringAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PowerSource::Attributes::BatANSIDesignation::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PowerSourceCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRCharStringAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeBatANSIDesignationWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                        completionHandler:
                                            (void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = PowerSource::Attributes::BatANSIDesignation::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeBatIECDesignationWithCompletionHandler:(void (^)(NSString * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PowerSource::Attributes::BatIECDesignation::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PowerSourceCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeBatIECDesignationWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRCharStringAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PowerSource::Attributes::BatIECDesignation::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PowerSourceCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRCharStringAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeBatIECDesignationWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = PowerSource::Attributes::BatIECDesignation::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeBatApprovedChemistryWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PowerSource::Attributes::BatApprovedChemistry::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PowerSourceCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeBatApprovedChemistryWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PowerSource::Attributes::BatApprovedChemistry::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PowerSourceCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeBatApprovedChemistryWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = PowerSource::Attributes::BatApprovedChemistry::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeBatCapacityWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PowerSource::Attributes::BatCapacity::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PowerSourceCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeBatCapacityWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PowerSource::Attributes::BatCapacity::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PowerSourceCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeBatCapacityWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = PowerSource::Attributes::BatCapacity::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeBatQuantityWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PowerSource::Attributes::BatQuantity::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PowerSourceCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeBatQuantityWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PowerSource::Attributes::BatQuantity::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PowerSourceCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeBatQuantityWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = PowerSource::Attributes::BatQuantity::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeBatChargeStateWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    new MTRPowerSourceClusterBatChargeStateAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PowerSource::Attributes::BatChargeState::TypeInfo;
            auto successFn = Callback<PowerSourceClusterBatChargeStateAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PowerSourceCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeBatChargeStateWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRPowerSourceClusterBatChargeStateAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PowerSource::Attributes::BatChargeState::TypeInfo;
            auto successFn = Callback<PowerSourceClusterBatChargeStateAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PowerSourceCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRPowerSourceClusterBatChargeStateAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeBatChargeStateWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRPowerSourceClusterBatChargeStateAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PowerSource::Attributes::BatChargeState::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<PowerSourceClusterBatChargeStateAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeBatTimeToFullChargeWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRNullableInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PowerSource::Attributes::BatTimeToFullCharge::TypeInfo;
            auto successFn = Callback<NullableInt32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PowerSourceCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeBatTimeToFullChargeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PowerSource::Attributes::BatTimeToFullCharge::TypeInfo;
            auto successFn = Callback<NullableInt32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PowerSourceCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeBatTimeToFullChargeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = PowerSource::Attributes::BatTimeToFullCharge::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeBatFunctionalWhileChargingWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))completionHandler
{
    new MTRBooleanAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PowerSource::Attributes::BatFunctionalWhileCharging::TypeInfo;
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PowerSourceCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeBatFunctionalWhileChargingWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                                             params:(MTRSubscribeParams * _Nullable)params
                                            subscriptionEstablished:
                                                (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                      reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRBooleanAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PowerSource::Attributes::BatFunctionalWhileCharging::TypeInfo;
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PowerSourceCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRBooleanAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeBatFunctionalWhileChargingWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                         endpoint:(NSNumber *)endpoint
                                                            queue:(dispatch_queue_t)queue
                                                completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))completionHandler
{
    new MTRBooleanAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = PowerSource::Attributes::BatFunctionalWhileCharging::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeBatChargingCurrentWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                 NSError * _Nullable error))completionHandler
{
    new MTRNullableInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PowerSource::Attributes::BatChargingCurrent::TypeInfo;
            auto successFn = Callback<NullableInt32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PowerSourceCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeBatChargingCurrentWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                maxInterval:(NSNumber * _Nonnull)maxInterval
                                                     params:(MTRSubscribeParams * _Nullable)params
                                    subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                              reportHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PowerSource::Attributes::BatChargingCurrent::TypeInfo;
            auto successFn = Callback<NullableInt32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PowerSourceCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeBatChargingCurrentWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                        completionHandler:
                                            (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = PowerSource::Attributes::BatChargingCurrent::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeActiveBatChargeFaultsWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                    NSError * _Nullable error))completionHandler
{
    new MTRPowerSourceActiveBatChargeFaultsListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PowerSource::Attributes::ActiveBatChargeFaults::TypeInfo;
            auto successFn = Callback<PowerSourceActiveBatChargeFaultsListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PowerSourceCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeActiveBatChargeFaultsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                   maxInterval:(NSNumber * _Nonnull)maxInterval
                                                        params:(MTRSubscribeParams * _Nullable)params
                                       subscriptionEstablished:
                                           (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                 reportHandler:
                                                     (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRPowerSourceActiveBatChargeFaultsListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PowerSource::Attributes::ActiveBatChargeFaults::TypeInfo;
            auto successFn = Callback<PowerSourceActiveBatChargeFaultsListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PowerSourceCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRPowerSourceActiveBatChargeFaultsListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeActiveBatChargeFaultsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                           completionHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRPowerSourceActiveBatChargeFaultsListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PowerSource::Attributes::ActiveBatChargeFaults::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<PowerSourceActiveBatChargeFaultsListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRPowerSourceGeneratedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PowerSource::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<PowerSourceGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PowerSourceCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRPowerSourceGeneratedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PowerSource::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<PowerSourceGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PowerSourceCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRPowerSourceGeneratedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRPowerSourceGeneratedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PowerSource::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<PowerSourceGeneratedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRPowerSourceAcceptedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PowerSource::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<PowerSourceAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PowerSourceCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRPowerSourceAcceptedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PowerSource::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<PowerSourceAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PowerSourceCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRPowerSourceAcceptedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRPowerSourceAcceptedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PowerSource::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<PowerSourceAcceptedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRPowerSourceAttributeListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PowerSource::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<PowerSourceAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PowerSourceCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRPowerSourceAttributeListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PowerSource::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<PowerSourceAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PowerSourceCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRPowerSourceAttributeListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRPowerSourceAttributeListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PowerSource::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<PowerSourceAttributeListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PowerSource::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PowerSourceCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PowerSource::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PowerSourceCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = PowerSource::Attributes::FeatureMap::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PowerSource::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PowerSourceCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PowerSource::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PowerSourceCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = PowerSource::Attributes::ClusterRevision::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

@end

@implementation MTRBaseClusterGeneralCommissioning

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = endpoint;
    }
    return self;
}

- (void)armFailSafeWithParams:(MTRGeneralCommissioningClusterArmFailSafeParams *)params
            completionHandler:(void (^)(MTRGeneralCommissioningClusterArmFailSafeResponseParams * _Nullable data,
                                  NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRGeneralCommissioningClusterArmFailSafeResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            GeneralCommissioning::Commands::ArmFailSafe::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.expiryLengthSeconds = params.expiryLengthSeconds.unsignedShortValue;
            request.breadcrumb = params.breadcrumb.unsignedLongLongValue;

            auto successFn = Callback<GeneralCommissioningClusterArmFailSafeResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::GeneralCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)setRegulatoryConfigWithParams:(MTRGeneralCommissioningClusterSetRegulatoryConfigParams *)params
                    completionHandler:(void (^)(MTRGeneralCommissioningClusterSetRegulatoryConfigResponseParams * _Nullable data,
                                          NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRGeneralCommissioningClusterSetRegulatoryConfigResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            GeneralCommissioning::Commands::SetRegulatoryConfig::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.newRegulatoryConfig = static_cast<std::remove_reference_t<decltype(request.newRegulatoryConfig)>>(
                params.newRegulatoryConfig.unsignedCharValue);
            request.countryCode = [self asCharSpan:params.countryCode];
            request.breadcrumb = params.breadcrumb.unsignedLongLongValue;

            auto successFn = Callback<GeneralCommissioningClusterSetRegulatoryConfigResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::GeneralCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)commissioningCompleteWithCompletionHandler:
    (void (^)(MTRGeneralCommissioningClusterCommissioningCompleteResponseParams * _Nullable data,
        NSError * _Nullable error))completionHandler
{
    [self commissioningCompleteWithParams:nil completionHandler:completionHandler];
}
- (void)commissioningCompleteWithParams:(MTRGeneralCommissioningClusterCommissioningCompleteParams * _Nullable)params
                      completionHandler:
                          (void (^)(MTRGeneralCommissioningClusterCommissioningCompleteResponseParams * _Nullable data,
                              NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRGeneralCommissioningClusterCommissioningCompleteResponseCallbackBridge(self.callbackQueue, self.device,
        completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            GeneralCommissioning::Commands::CommissioningComplete::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }

            auto successFn
                = Callback<GeneralCommissioningClusterCommissioningCompleteResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::GeneralCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)readAttributeBreadcrumbWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt64uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = GeneralCommissioning::Attributes::Breadcrumb::TypeInfo;
            auto successFn = Callback<Int64uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::GeneralCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeBreadcrumbWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeBreadcrumbWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeBreadcrumbWithValue:(NSNumber * _Nonnull)value
                                   params:(MTRWriteParams * _Nullable)params
                        completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = GeneralCommissioning::Attributes::Breadcrumb::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedLongLongValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::GeneralCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeBreadcrumbWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt64uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = GeneralCommissioning::Attributes::Breadcrumb::TypeInfo;
            auto successFn = Callback<Int64uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::GeneralCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt64uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeBreadcrumbWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt64uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = GeneralCommissioning::Attributes::Breadcrumb::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int64uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeBasicCommissioningInfoWithCompletionHandler:
    (void (^)(MTRGeneralCommissioningClusterBasicCommissioningInfo * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRGeneralCommissioningBasicCommissioningInfoStructAttributeCallbackBridge(self.callbackQueue, self.device,
        completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = GeneralCommissioning::Attributes::BasicCommissioningInfo::TypeInfo;
            auto successFn = Callback<GeneralCommissioningBasicCommissioningInfoStructAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::GeneralCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)
    subscribeAttributeBasicCommissioningInfoWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                maxInterval:(NSNumber * _Nonnull)maxInterval
                                                     params:(MTRSubscribeParams * _Nullable)params
                                    subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                              reportHandler:
                                                  (void (^)(MTRGeneralCommissioningClusterBasicCommissioningInfo * _Nullable value,
                                                      NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRGeneralCommissioningBasicCommissioningInfoStructAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = GeneralCommissioning::Attributes::BasicCommissioningInfo::TypeInfo;
            auto successFn = Callback<GeneralCommissioningBasicCommissioningInfoStructAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::GeneralCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRGeneralCommissioningBasicCommissioningInfoStructAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished,
                nil, params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeBasicCommissioningInfoWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                            completionHandler:
                                                (void (^)(MTRGeneralCommissioningClusterBasicCommissioningInfo * _Nullable value,
                                                    NSError * _Nullable error))completionHandler
{
    new MTRGeneralCommissioningBasicCommissioningInfoStructAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = GeneralCommissioning::Attributes::BasicCommissioningInfo::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn
                    = Callback<GeneralCommissioningBasicCommissioningInfoStructAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeRegulatoryConfigWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    new MTRGeneralCommissioningClusterRegulatoryLocationTypeAttributeCallbackBridge(self.callbackQueue, self.device,
        completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = GeneralCommissioning::Attributes::RegulatoryConfig::TypeInfo;
            auto successFn = Callback<GeneralCommissioningClusterRegulatoryLocationTypeAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::GeneralCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeRegulatoryConfigWithMinInterval:(NSNumber * _Nonnull)minInterval
                                              maxInterval:(NSNumber * _Nonnull)maxInterval
                                                   params:(MTRSubscribeParams * _Nullable)params
                                  subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                            reportHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRGeneralCommissioningClusterRegulatoryLocationTypeAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = GeneralCommissioning::Attributes::RegulatoryConfig::TypeInfo;
            auto successFn = Callback<GeneralCommissioningClusterRegulatoryLocationTypeAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::GeneralCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRGeneralCommissioningClusterRegulatoryLocationTypeAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished,
                nil, params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeRegulatoryConfigWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRGeneralCommissioningClusterRegulatoryLocationTypeAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = GeneralCommissioning::Attributes::RegulatoryConfig::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn
                    = Callback<GeneralCommissioningClusterRegulatoryLocationTypeAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeLocationCapabilityWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                 NSError * _Nullable error))completionHandler
{
    new MTRGeneralCommissioningClusterRegulatoryLocationTypeAttributeCallbackBridge(self.callbackQueue, self.device,
        completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = GeneralCommissioning::Attributes::LocationCapability::TypeInfo;
            auto successFn = Callback<GeneralCommissioningClusterRegulatoryLocationTypeAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::GeneralCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeLocationCapabilityWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                maxInterval:(NSNumber * _Nonnull)maxInterval
                                                     params:(MTRSubscribeParams * _Nullable)params
                                    subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                              reportHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRGeneralCommissioningClusterRegulatoryLocationTypeAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = GeneralCommissioning::Attributes::LocationCapability::TypeInfo;
            auto successFn = Callback<GeneralCommissioningClusterRegulatoryLocationTypeAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::GeneralCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRGeneralCommissioningClusterRegulatoryLocationTypeAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished,
                nil, params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeLocationCapabilityWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                        completionHandler:
                                            (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRGeneralCommissioningClusterRegulatoryLocationTypeAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = GeneralCommissioning::Attributes::LocationCapability::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn
                    = Callback<GeneralCommissioningClusterRegulatoryLocationTypeAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeSupportsConcurrentConnectionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))completionHandler
{
    new MTRBooleanAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = GeneralCommissioning::Attributes::SupportsConcurrentConnection::TypeInfo;
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::GeneralCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeSupportsConcurrentConnectionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                                               params:(MTRSubscribeParams * _Nullable)params
                                              subscriptionEstablished:
                                                  (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                        reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                          NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRBooleanAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = GeneralCommissioning::Attributes::SupportsConcurrentConnection::TypeInfo;
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::GeneralCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRBooleanAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeSupportsConcurrentConnectionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                           endpoint:(NSNumber *)endpoint
                                                              queue:(dispatch_queue_t)queue
                                                  completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))completionHandler
{
    new MTRBooleanAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = GeneralCommissioning::Attributes::SupportsConcurrentConnection::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRGeneralCommissioningGeneratedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = GeneralCommissioning::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<GeneralCommissioningGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::GeneralCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRGeneralCommissioningGeneratedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = GeneralCommissioning::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<GeneralCommissioningGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::GeneralCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRGeneralCommissioningGeneratedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRGeneralCommissioningGeneratedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = GeneralCommissioning::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<GeneralCommissioningGeneratedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRGeneralCommissioningAcceptedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = GeneralCommissioning::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<GeneralCommissioningAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::GeneralCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRGeneralCommissioningAcceptedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = GeneralCommissioning::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<GeneralCommissioningAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::GeneralCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRGeneralCommissioningAcceptedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRGeneralCommissioningAcceptedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = GeneralCommissioning::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<GeneralCommissioningAcceptedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRGeneralCommissioningAttributeListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = GeneralCommissioning::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<GeneralCommissioningAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::GeneralCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRGeneralCommissioningAttributeListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = GeneralCommissioning::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<GeneralCommissioningAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::GeneralCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRGeneralCommissioningAttributeListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRGeneralCommissioningAttributeListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = GeneralCommissioning::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<GeneralCommissioningAttributeListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = GeneralCommissioning::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::GeneralCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = GeneralCommissioning::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::GeneralCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = GeneralCommissioning::Attributes::FeatureMap::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = GeneralCommissioning::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::GeneralCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = GeneralCommissioning::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::GeneralCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = GeneralCommissioning::Attributes::ClusterRevision::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

@end

@implementation MTRBaseClusterNetworkCommissioning

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = endpoint;
    }
    return self;
}

- (void)scanNetworksWithParams:(MTRNetworkCommissioningClusterScanNetworksParams * _Nullable)params
             completionHandler:(void (^)(MTRNetworkCommissioningClusterScanNetworksResponseParams * _Nullable data,
                                   NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRNetworkCommissioningClusterScanNetworksResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            NetworkCommissioning::Commands::ScanNetworks::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            if (params != nil) {
                if (params.ssid != nil) {
                    auto & definedValue_0 = request.ssid.Emplace();
                    if (params.ssid == nil) {
                        definedValue_0.SetNull();
                    } else {
                        auto & nonNullValue_1 = definedValue_0.SetNonNull();
                        nonNullValue_1 = [self asByteSpan:params.ssid];
                    }
                }
                if (params.breadcrumb != nil) {
                    auto & definedValue_0 = request.breadcrumb.Emplace();
                    definedValue_0 = params.breadcrumb.unsignedLongLongValue;
                }
            }

            auto successFn = Callback<NetworkCommissioningClusterScanNetworksResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::NetworkCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)addOrUpdateWiFiNetworkWithParams:(MTRNetworkCommissioningClusterAddOrUpdateWiFiNetworkParams *)params
                       completionHandler:(void (^)(MTRNetworkCommissioningClusterNetworkConfigResponseParams * _Nullable data,
                                             NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRNetworkCommissioningClusterNetworkConfigResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            NetworkCommissioning::Commands::AddOrUpdateWiFiNetwork::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.ssid = [self asByteSpan:params.ssid];
            request.credentials = [self asByteSpan:params.credentials];
            if (params.breadcrumb != nil) {
                auto & definedValue_0 = request.breadcrumb.Emplace();
                definedValue_0 = params.breadcrumb.unsignedLongLongValue;
            }

            auto successFn = Callback<NetworkCommissioningClusterNetworkConfigResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::NetworkCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)addOrUpdateThreadNetworkWithParams:(MTRNetworkCommissioningClusterAddOrUpdateThreadNetworkParams *)params
                         completionHandler:(void (^)(MTRNetworkCommissioningClusterNetworkConfigResponseParams * _Nullable data,
                                               NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRNetworkCommissioningClusterNetworkConfigResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            NetworkCommissioning::Commands::AddOrUpdateThreadNetwork::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.operationalDataset = [self asByteSpan:params.operationalDataset];
            if (params.breadcrumb != nil) {
                auto & definedValue_0 = request.breadcrumb.Emplace();
                definedValue_0 = params.breadcrumb.unsignedLongLongValue;
            }

            auto successFn = Callback<NetworkCommissioningClusterNetworkConfigResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::NetworkCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)removeNetworkWithParams:(MTRNetworkCommissioningClusterRemoveNetworkParams *)params
              completionHandler:(void (^)(MTRNetworkCommissioningClusterNetworkConfigResponseParams * _Nullable data,
                                    NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRNetworkCommissioningClusterNetworkConfigResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            NetworkCommissioning::Commands::RemoveNetwork::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.networkID = [self asByteSpan:params.networkID];
            if (params.breadcrumb != nil) {
                auto & definedValue_0 = request.breadcrumb.Emplace();
                definedValue_0 = params.breadcrumb.unsignedLongLongValue;
            }

            auto successFn = Callback<NetworkCommissioningClusterNetworkConfigResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::NetworkCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)connectNetworkWithParams:(MTRNetworkCommissioningClusterConnectNetworkParams *)params
               completionHandler:(void (^)(MTRNetworkCommissioningClusterConnectNetworkResponseParams * _Nullable data,
                                     NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRNetworkCommissioningClusterConnectNetworkResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            NetworkCommissioning::Commands::ConnectNetwork::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.networkID = [self asByteSpan:params.networkID];
            if (params.breadcrumb != nil) {
                auto & definedValue_0 = request.breadcrumb.Emplace();
                definedValue_0 = params.breadcrumb.unsignedLongLongValue;
            }

            auto successFn = Callback<NetworkCommissioningClusterConnectNetworkResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::NetworkCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)reorderNetworkWithParams:(MTRNetworkCommissioningClusterReorderNetworkParams *)params
               completionHandler:(void (^)(MTRNetworkCommissioningClusterNetworkConfigResponseParams * _Nullable data,
                                     NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRNetworkCommissioningClusterNetworkConfigResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            NetworkCommissioning::Commands::ReorderNetwork::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.networkID = [self asByteSpan:params.networkID];
            request.networkIndex = params.networkIndex.unsignedCharValue;
            if (params.breadcrumb != nil) {
                auto & definedValue_0 = request.breadcrumb.Emplace();
                definedValue_0 = params.breadcrumb.unsignedLongLongValue;
            }

            auto successFn = Callback<NetworkCommissioningClusterNetworkConfigResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::NetworkCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)readAttributeMaxNetworksWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = NetworkCommissioning::Attributes::MaxNetworks::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::NetworkCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeMaxNetworksWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = NetworkCommissioning::Attributes::MaxNetworks::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::NetworkCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeMaxNetworksWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = NetworkCommissioning::Attributes::MaxNetworks::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeNetworksWithCompletionHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNetworkCommissioningNetworksListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = NetworkCommissioning::Attributes::Networks::TypeInfo;
            auto successFn = Callback<NetworkCommissioningNetworksListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::NetworkCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeNetworksWithMinInterval:(NSNumber * _Nonnull)minInterval
                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                           params:(MTRSubscribeParams * _Nullable)params
                          subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                    reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNetworkCommissioningNetworksListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = NetworkCommissioning::Attributes::Networks::TypeInfo;
            auto successFn = Callback<NetworkCommissioningNetworksListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::NetworkCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNetworkCommissioningNetworksListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeNetworksWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                       endpoint:(NSNumber *)endpoint
                                          queue:(dispatch_queue_t)queue
                              completionHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNetworkCommissioningNetworksListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = NetworkCommissioning::Attributes::Networks::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<NetworkCommissioningNetworksListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeScanMaxTimeSecondsWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                 NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = NetworkCommissioning::Attributes::ScanMaxTimeSeconds::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::NetworkCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeScanMaxTimeSecondsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                maxInterval:(NSNumber * _Nonnull)maxInterval
                                                     params:(MTRSubscribeParams * _Nullable)params
                                    subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                              reportHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = NetworkCommissioning::Attributes::ScanMaxTimeSeconds::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::NetworkCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeScanMaxTimeSecondsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                        completionHandler:
                                            (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = NetworkCommissioning::Attributes::ScanMaxTimeSeconds::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeConnectMaxTimeSecondsWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                    NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = NetworkCommissioning::Attributes::ConnectMaxTimeSeconds::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::NetworkCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeConnectMaxTimeSecondsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                   maxInterval:(NSNumber * _Nonnull)maxInterval
                                                        params:(MTRSubscribeParams * _Nullable)params
                                       subscriptionEstablished:
                                           (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                 reportHandler:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = NetworkCommissioning::Attributes::ConnectMaxTimeSeconds::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::NetworkCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeConnectMaxTimeSecondsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                           completionHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = NetworkCommissioning::Attributes::ConnectMaxTimeSeconds::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeInterfaceEnabledWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    new MTRBooleanAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = NetworkCommissioning::Attributes::InterfaceEnabled::TypeInfo;
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::NetworkCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeInterfaceEnabledWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeInterfaceEnabledWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeInterfaceEnabledWithValue:(NSNumber * _Nonnull)value
                                         params:(MTRWriteParams * _Nullable)params
                              completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = NetworkCommissioning::Attributes::InterfaceEnabled::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.boolValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::NetworkCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeInterfaceEnabledWithMinInterval:(NSNumber * _Nonnull)minInterval
                                              maxInterval:(NSNumber * _Nonnull)maxInterval
                                                   params:(MTRSubscribeParams * _Nullable)params
                                  subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                            reportHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRBooleanAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = NetworkCommissioning::Attributes::InterfaceEnabled::TypeInfo;
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::NetworkCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRBooleanAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeInterfaceEnabledWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBooleanAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = NetworkCommissioning::Attributes::InterfaceEnabled::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeLastNetworkingStatusWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRNullableNetworkCommissioningClusterNetworkCommissioningStatusAttributeCallbackBridge(self.callbackQueue, self.device,
        completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = NetworkCommissioning::Attributes::LastNetworkingStatus::TypeInfo;
            auto successFn
                = Callback<NullableNetworkCommissioningClusterNetworkCommissioningStatusAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::NetworkCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeLastNetworkingStatusWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableNetworkCommissioningClusterNetworkCommissioningStatusAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = NetworkCommissioning::Attributes::LastNetworkingStatus::TypeInfo;
            auto successFn
                = Callback<NullableNetworkCommissioningClusterNetworkCommissioningStatusAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::NetworkCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableNetworkCommissioningClusterNetworkCommissioningStatusAttributeCallbackSubscriptionBridge::
                    OnSubscriptionEstablished,
                nil, params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeLastNetworkingStatusWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableNetworkCommissioningClusterNetworkCommissioningStatusAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = NetworkCommissioning::Attributes::LastNetworkingStatus::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn
                    = Callback<NullableNetworkCommissioningClusterNetworkCommissioningStatusAttributeCallback>::FromCancelable(
                        success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeLastNetworkIDWithCompletionHandler:(void (^)(
                                                            NSData * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableOctetStringAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = NetworkCommissioning::Attributes::LastNetworkID::TypeInfo;
            auto successFn = Callback<NullableOctetStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::NetworkCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeLastNetworkIDWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSData * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableOctetStringAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = NetworkCommissioning::Attributes::LastNetworkID::TypeInfo;
            auto successFn = Callback<NullableOctetStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::NetworkCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableOctetStringAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeLastNetworkIDWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSData * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableOctetStringAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = NetworkCommissioning::Attributes::LastNetworkID::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableOctetStringAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeLastConnectErrorValueWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                    NSError * _Nullable error))completionHandler
{
    new MTRNullableInt32sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = NetworkCommissioning::Attributes::LastConnectErrorValue::TypeInfo;
            auto successFn = Callback<NullableInt32sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::NetworkCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeLastConnectErrorValueWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                   maxInterval:(NSNumber * _Nonnull)maxInterval
                                                        params:(MTRSubscribeParams * _Nullable)params
                                       subscriptionEstablished:
                                           (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                 reportHandler:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt32sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = NetworkCommissioning::Attributes::LastConnectErrorValue::TypeInfo;
            auto successFn = Callback<NullableInt32sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::NetworkCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt32sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeLastConnectErrorValueWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                           completionHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt32sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = NetworkCommissioning::Attributes::LastConnectErrorValue::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt32sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRNetworkCommissioningGeneratedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = NetworkCommissioning::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<NetworkCommissioningGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::NetworkCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNetworkCommissioningGeneratedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = NetworkCommissioning::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<NetworkCommissioningGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::NetworkCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNetworkCommissioningGeneratedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNetworkCommissioningGeneratedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = NetworkCommissioning::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<NetworkCommissioningGeneratedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRNetworkCommissioningAcceptedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = NetworkCommissioning::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<NetworkCommissioningAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::NetworkCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNetworkCommissioningAcceptedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = NetworkCommissioning::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<NetworkCommissioningAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::NetworkCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNetworkCommissioningAcceptedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNetworkCommissioningAcceptedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = NetworkCommissioning::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<NetworkCommissioningAcceptedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNetworkCommissioningAttributeListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = NetworkCommissioning::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<NetworkCommissioningAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::NetworkCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNetworkCommissioningAttributeListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = NetworkCommissioning::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<NetworkCommissioningAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::NetworkCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNetworkCommissioningAttributeListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNetworkCommissioningAttributeListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = NetworkCommissioning::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<NetworkCommissioningAttributeListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = NetworkCommissioning::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::NetworkCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = NetworkCommissioning::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::NetworkCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = NetworkCommissioning::Attributes::FeatureMap::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = NetworkCommissioning::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::NetworkCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = NetworkCommissioning::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::NetworkCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = NetworkCommissioning::Attributes::ClusterRevision::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

@end

@implementation MTRBaseClusterDiagnosticLogs

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = endpoint;
    }
    return self;
}

- (void)retrieveLogsRequestWithParams:(MTRDiagnosticLogsClusterRetrieveLogsRequestParams *)params
                    completionHandler:(void (^)(MTRDiagnosticLogsClusterRetrieveLogsResponseParams * _Nullable data,
                                          NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRDiagnosticLogsClusterRetrieveLogsResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            DiagnosticLogs::Commands::RetrieveLogsRequest::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.intent = static_cast<std::remove_reference_t<decltype(request.intent)>>(params.intent.unsignedCharValue);
            request.requestedProtocol = static_cast<std::remove_reference_t<decltype(request.requestedProtocol)>>(
                params.requestedProtocol.unsignedCharValue);
            request.transferFileDesignator = [self asByteSpan:params.transferFileDesignator];

            auto successFn = Callback<DiagnosticLogsClusterRetrieveLogsResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DiagnosticLogsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRDiagnosticLogsGeneratedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = DiagnosticLogs::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<DiagnosticLogsGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DiagnosticLogsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRDiagnosticLogsGeneratedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = DiagnosticLogs::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<DiagnosticLogsGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::DiagnosticLogsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRDiagnosticLogsGeneratedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRDiagnosticLogsGeneratedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = DiagnosticLogs::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<DiagnosticLogsGeneratedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRDiagnosticLogsAcceptedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = DiagnosticLogs::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<DiagnosticLogsAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DiagnosticLogsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRDiagnosticLogsAcceptedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = DiagnosticLogs::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<DiagnosticLogsAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::DiagnosticLogsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRDiagnosticLogsAcceptedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRDiagnosticLogsAcceptedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = DiagnosticLogs::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<DiagnosticLogsAcceptedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRDiagnosticLogsAttributeListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = DiagnosticLogs::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<DiagnosticLogsAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DiagnosticLogsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRDiagnosticLogsAttributeListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = DiagnosticLogs::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<DiagnosticLogsAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::DiagnosticLogsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRDiagnosticLogsAttributeListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRDiagnosticLogsAttributeListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = DiagnosticLogs::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<DiagnosticLogsAttributeListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = DiagnosticLogs::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DiagnosticLogsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = DiagnosticLogs::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::DiagnosticLogsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = DiagnosticLogs::Attributes::FeatureMap::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = DiagnosticLogs::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DiagnosticLogsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = DiagnosticLogs::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::DiagnosticLogsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = DiagnosticLogs::Attributes::ClusterRevision::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

@end

@implementation MTRBaseClusterGeneralDiagnostics

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = endpoint;
    }
    return self;
}

- (void)testEventTriggerWithParams:(MTRGeneralDiagnosticsClusterTestEventTriggerParams *)params
                 completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            GeneralDiagnostics::Commands::TestEventTrigger::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.enableKey = [self asByteSpan:params.enableKey];
            request.eventTrigger = params.eventTrigger.unsignedLongLongValue;

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::GeneralDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)readAttributeNetworkInterfacesWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    new MTRGeneralDiagnosticsNetworkInterfacesListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = GeneralDiagnostics::Attributes::NetworkInterfaces::TypeInfo;
            auto successFn = Callback<GeneralDiagnosticsNetworkInterfacesListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::GeneralDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeNetworkInterfacesWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRGeneralDiagnosticsNetworkInterfacesListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = GeneralDiagnostics::Attributes::NetworkInterfaces::TypeInfo;
            auto successFn = Callback<GeneralDiagnosticsNetworkInterfacesListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::GeneralDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRGeneralDiagnosticsNetworkInterfacesListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeNetworkInterfacesWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRGeneralDiagnosticsNetworkInterfacesListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = GeneralDiagnostics::Attributes::NetworkInterfaces::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<GeneralDiagnosticsNetworkInterfacesListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeRebootCountWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = GeneralDiagnostics::Attributes::RebootCount::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::GeneralDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeRebootCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = GeneralDiagnostics::Attributes::RebootCount::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::GeneralDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeRebootCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = GeneralDiagnostics::Attributes::RebootCount::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeUpTimeWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt64uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = GeneralDiagnostics::Attributes::UpTime::TypeInfo;
            auto successFn = Callback<Int64uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::GeneralDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeUpTimeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                         params:(MTRSubscribeParams * _Nullable)params
                        subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt64uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = GeneralDiagnostics::Attributes::UpTime::TypeInfo;
            auto successFn = Callback<Int64uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::GeneralDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt64uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeUpTimeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                     endpoint:(NSNumber *)endpoint
                                        queue:(dispatch_queue_t)queue
                            completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt64uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = GeneralDiagnostics::Attributes::UpTime::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int64uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeTotalOperationalHoursWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                    NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = GeneralDiagnostics::Attributes::TotalOperationalHours::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::GeneralDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeTotalOperationalHoursWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                   maxInterval:(NSNumber * _Nonnull)maxInterval
                                                        params:(MTRSubscribeParams * _Nullable)params
                                       subscriptionEstablished:
                                           (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                 reportHandler:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = GeneralDiagnostics::Attributes::TotalOperationalHours::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::GeneralDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeTotalOperationalHoursWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                           completionHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = GeneralDiagnostics::Attributes::TotalOperationalHours::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeBootReasonsWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = GeneralDiagnostics::Attributes::BootReasons::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::GeneralDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeBootReasonsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = GeneralDiagnostics::Attributes::BootReasons::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::GeneralDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeBootReasonsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = GeneralDiagnostics::Attributes::BootReasons::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeActiveHardwareFaultsWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRGeneralDiagnosticsActiveHardwareFaultsListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = GeneralDiagnostics::Attributes::ActiveHardwareFaults::TypeInfo;
            auto successFn = Callback<GeneralDiagnosticsActiveHardwareFaultsListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::GeneralDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeActiveHardwareFaultsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRGeneralDiagnosticsActiveHardwareFaultsListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = GeneralDiagnostics::Attributes::ActiveHardwareFaults::TypeInfo;
            auto successFn = Callback<GeneralDiagnosticsActiveHardwareFaultsListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::GeneralDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRGeneralDiagnosticsActiveHardwareFaultsListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeActiveHardwareFaultsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRGeneralDiagnosticsActiveHardwareFaultsListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = GeneralDiagnostics::Attributes::ActiveHardwareFaults::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<GeneralDiagnosticsActiveHardwareFaultsListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeActiveRadioFaultsWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    new MTRGeneralDiagnosticsActiveRadioFaultsListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = GeneralDiagnostics::Attributes::ActiveRadioFaults::TypeInfo;
            auto successFn = Callback<GeneralDiagnosticsActiveRadioFaultsListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::GeneralDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeActiveRadioFaultsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRGeneralDiagnosticsActiveRadioFaultsListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = GeneralDiagnostics::Attributes::ActiveRadioFaults::TypeInfo;
            auto successFn = Callback<GeneralDiagnosticsActiveRadioFaultsListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::GeneralDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRGeneralDiagnosticsActiveRadioFaultsListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeActiveRadioFaultsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRGeneralDiagnosticsActiveRadioFaultsListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = GeneralDiagnostics::Attributes::ActiveRadioFaults::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<GeneralDiagnosticsActiveRadioFaultsListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeActiveNetworkFaultsWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRGeneralDiagnosticsActiveNetworkFaultsListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = GeneralDiagnostics::Attributes::ActiveNetworkFaults::TypeInfo;
            auto successFn = Callback<GeneralDiagnosticsActiveNetworkFaultsListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::GeneralDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeActiveNetworkFaultsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRGeneralDiagnosticsActiveNetworkFaultsListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = GeneralDiagnostics::Attributes::ActiveNetworkFaults::TypeInfo;
            auto successFn = Callback<GeneralDiagnosticsActiveNetworkFaultsListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::GeneralDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRGeneralDiagnosticsActiveNetworkFaultsListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeActiveNetworkFaultsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRGeneralDiagnosticsActiveNetworkFaultsListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = GeneralDiagnostics::Attributes::ActiveNetworkFaults::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<GeneralDiagnosticsActiveNetworkFaultsListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeTestEventTriggersEnabledWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))completionHandler
{
    new MTRBooleanAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = GeneralDiagnostics::Attributes::TestEventTriggersEnabled::TypeInfo;
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::GeneralDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeTestEventTriggersEnabledWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                                           params:(MTRSubscribeParams * _Nullable)params
                                          subscriptionEstablished:
                                              (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                    reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRBooleanAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = GeneralDiagnostics::Attributes::TestEventTriggersEnabled::TypeInfo;
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::GeneralDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRBooleanAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeTestEventTriggersEnabledWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                       endpoint:(NSNumber *)endpoint
                                                          queue:(dispatch_queue_t)queue
                                              completionHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBooleanAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = GeneralDiagnostics::Attributes::TestEventTriggersEnabled::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRGeneralDiagnosticsGeneratedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = GeneralDiagnostics::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<GeneralDiagnosticsGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::GeneralDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRGeneralDiagnosticsGeneratedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = GeneralDiagnostics::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<GeneralDiagnosticsGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::GeneralDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRGeneralDiagnosticsGeneratedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRGeneralDiagnosticsGeneratedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = GeneralDiagnostics::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<GeneralDiagnosticsGeneratedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRGeneralDiagnosticsAcceptedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = GeneralDiagnostics::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<GeneralDiagnosticsAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::GeneralDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRGeneralDiagnosticsAcceptedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = GeneralDiagnostics::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<GeneralDiagnosticsAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::GeneralDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRGeneralDiagnosticsAcceptedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRGeneralDiagnosticsAcceptedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = GeneralDiagnostics::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<GeneralDiagnosticsAcceptedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRGeneralDiagnosticsAttributeListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = GeneralDiagnostics::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<GeneralDiagnosticsAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::GeneralDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRGeneralDiagnosticsAttributeListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = GeneralDiagnostics::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<GeneralDiagnosticsAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::GeneralDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRGeneralDiagnosticsAttributeListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRGeneralDiagnosticsAttributeListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = GeneralDiagnostics::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<GeneralDiagnosticsAttributeListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = GeneralDiagnostics::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::GeneralDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = GeneralDiagnostics::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::GeneralDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = GeneralDiagnostics::Attributes::FeatureMap::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = GeneralDiagnostics::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::GeneralDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = GeneralDiagnostics::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::GeneralDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = GeneralDiagnostics::Attributes::ClusterRevision::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

@end

@implementation MTRBaseClusterSoftwareDiagnostics

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = endpoint;
    }
    return self;
}

- (void)resetWatermarksWithCompletionHandler:(StatusCompletion)completionHandler
{
    [self resetWatermarksWithParams:nil completionHandler:completionHandler];
}
- (void)resetWatermarksWithParams:(MTRSoftwareDiagnosticsClusterResetWatermarksParams * _Nullable)params
                completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            SoftwareDiagnostics::Commands::ResetWatermarks::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::SoftwareDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)readAttributeThreadMetricsWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRSoftwareDiagnosticsThreadMetricsListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = SoftwareDiagnostics::Attributes::ThreadMetrics::TypeInfo;
            auto successFn = Callback<SoftwareDiagnosticsThreadMetricsListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::SoftwareDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeThreadMetricsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRSoftwareDiagnosticsThreadMetricsListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = SoftwareDiagnostics::Attributes::ThreadMetrics::TypeInfo;
            auto successFn = Callback<SoftwareDiagnosticsThreadMetricsListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::SoftwareDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRSoftwareDiagnosticsThreadMetricsListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeThreadMetricsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRSoftwareDiagnosticsThreadMetricsListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = SoftwareDiagnostics::Attributes::ThreadMetrics::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<SoftwareDiagnosticsThreadMetricsListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeCurrentHeapFreeWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt64uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = SoftwareDiagnostics::Attributes::CurrentHeapFree::TypeInfo;
            auto successFn = Callback<Int64uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::SoftwareDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeCurrentHeapFreeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt64uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = SoftwareDiagnostics::Attributes::CurrentHeapFree::TypeInfo;
            auto successFn = Callback<Int64uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::SoftwareDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt64uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeCurrentHeapFreeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt64uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = SoftwareDiagnostics::Attributes::CurrentHeapFree::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int64uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeCurrentHeapUsedWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt64uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = SoftwareDiagnostics::Attributes::CurrentHeapUsed::TypeInfo;
            auto successFn = Callback<Int64uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::SoftwareDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeCurrentHeapUsedWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt64uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = SoftwareDiagnostics::Attributes::CurrentHeapUsed::TypeInfo;
            auto successFn = Callback<Int64uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::SoftwareDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt64uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeCurrentHeapUsedWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt64uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = SoftwareDiagnostics::Attributes::CurrentHeapUsed::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int64uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeCurrentHeapHighWatermarkWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))completionHandler
{
    new MTRInt64uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = SoftwareDiagnostics::Attributes::CurrentHeapHighWatermark::TypeInfo;
            auto successFn = Callback<Int64uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::SoftwareDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeCurrentHeapHighWatermarkWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                                           params:(MTRSubscribeParams * _Nullable)params
                                          subscriptionEstablished:
                                              (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                    reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt64uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = SoftwareDiagnostics::Attributes::CurrentHeapHighWatermark::TypeInfo;
            auto successFn = Callback<Int64uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::SoftwareDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt64uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeCurrentHeapHighWatermarkWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                       endpoint:(NSNumber *)endpoint
                                                          queue:(dispatch_queue_t)queue
                                              completionHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt64uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = SoftwareDiagnostics::Attributes::CurrentHeapHighWatermark::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int64uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRSoftwareDiagnosticsGeneratedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = SoftwareDiagnostics::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<SoftwareDiagnosticsGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::SoftwareDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRSoftwareDiagnosticsGeneratedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = SoftwareDiagnostics::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<SoftwareDiagnosticsGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::SoftwareDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRSoftwareDiagnosticsGeneratedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRSoftwareDiagnosticsGeneratedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = SoftwareDiagnostics::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<SoftwareDiagnosticsGeneratedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRSoftwareDiagnosticsAcceptedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = SoftwareDiagnostics::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<SoftwareDiagnosticsAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::SoftwareDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRSoftwareDiagnosticsAcceptedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = SoftwareDiagnostics::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<SoftwareDiagnosticsAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::SoftwareDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRSoftwareDiagnosticsAcceptedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRSoftwareDiagnosticsAcceptedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = SoftwareDiagnostics::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<SoftwareDiagnosticsAcceptedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRSoftwareDiagnosticsAttributeListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = SoftwareDiagnostics::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<SoftwareDiagnosticsAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::SoftwareDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRSoftwareDiagnosticsAttributeListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = SoftwareDiagnostics::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<SoftwareDiagnosticsAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::SoftwareDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRSoftwareDiagnosticsAttributeListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRSoftwareDiagnosticsAttributeListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = SoftwareDiagnostics::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<SoftwareDiagnosticsAttributeListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = SoftwareDiagnostics::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::SoftwareDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = SoftwareDiagnostics::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::SoftwareDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = SoftwareDiagnostics::Attributes::FeatureMap::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = SoftwareDiagnostics::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::SoftwareDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = SoftwareDiagnostics::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::SoftwareDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = SoftwareDiagnostics::Attributes::ClusterRevision::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

@end

@implementation MTRBaseClusterThreadNetworkDiagnostics

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = endpoint;
    }
    return self;
}

- (void)resetCountsWithCompletionHandler:(StatusCompletion)completionHandler
{
    [self resetCountsWithParams:nil completionHandler:completionHandler];
}
- (void)resetCountsWithParams:(MTRThreadNetworkDiagnosticsClusterResetCountsParams * _Nullable)params
            completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            ThreadNetworkDiagnostics::Commands::ResetCounts::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)readAttributeChannelWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::Channel::TypeInfo;
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeChannelWithMinInterval:(NSNumber * _Nonnull)minInterval
                                     maxInterval:(NSNumber * _Nonnull)maxInterval
                                          params:(MTRSubscribeParams * _Nullable)params
                         subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                   reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::Channel::TypeInfo;
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeChannelWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                      endpoint:(NSNumber *)endpoint
                                         queue:(dispatch_queue_t)queue
                             completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::Channel::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeRoutingRoleWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableThreadNetworkDiagnosticsClusterRoutingRoleAttributeCallbackBridge(self.callbackQueue, self.device,
        completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::RoutingRole::TypeInfo;
            auto successFn = Callback<NullableThreadNetworkDiagnosticsClusterRoutingRoleAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeRoutingRoleWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableThreadNetworkDiagnosticsClusterRoutingRoleAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::RoutingRole::TypeInfo;
            auto successFn = Callback<NullableThreadNetworkDiagnosticsClusterRoutingRoleAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableThreadNetworkDiagnosticsClusterRoutingRoleAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished,
                nil, params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeRoutingRoleWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableThreadNetworkDiagnosticsClusterRoutingRoleAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::RoutingRole::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn
                    = Callback<NullableThreadNetworkDiagnosticsClusterRoutingRoleAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeNetworkNameWithCompletionHandler:(void (^)(
                                                          NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableCharStringAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::NetworkName::TypeInfo;
            auto successFn = Callback<NullableCharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeNetworkNameWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableCharStringAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::NetworkName::TypeInfo;
            auto successFn = Callback<NullableCharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableCharStringAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeNetworkNameWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableCharStringAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::NetworkName::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableCharStringAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributePanIdWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::PanId::TypeInfo;
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributePanIdWithMinInterval:(NSNumber * _Nonnull)minInterval
                                   maxInterval:(NSNumber * _Nonnull)maxInterval
                                        params:(MTRSubscribeParams * _Nullable)params
                       subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::PanId::TypeInfo;
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributePanIdWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                    endpoint:(NSNumber *)endpoint
                                       queue:(dispatch_queue_t)queue
                           completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::PanId::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeExtendedPanIdWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt64uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::ExtendedPanId::TypeInfo;
            auto successFn = Callback<NullableInt64uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeExtendedPanIdWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt64uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::ExtendedPanId::TypeInfo;
            auto successFn = Callback<NullableInt64uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt64uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeExtendedPanIdWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt64uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::ExtendedPanId::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt64uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeMeshLocalPrefixWithCompletionHandler:(void (^)(
                                                              NSData * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableOctetStringAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::MeshLocalPrefix::TypeInfo;
            auto successFn = Callback<NullableOctetStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeMeshLocalPrefixWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSData * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableOctetStringAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::MeshLocalPrefix::TypeInfo;
            auto successFn = Callback<NullableOctetStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableOctetStringAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeMeshLocalPrefixWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSData * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableOctetStringAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::MeshLocalPrefix::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableOctetStringAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeOverrunCountWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt64uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::OverrunCount::TypeInfo;
            auto successFn = Callback<Int64uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeOverrunCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt64uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::OverrunCount::TypeInfo;
            auto successFn = Callback<Int64uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt64uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeOverrunCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt64uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::OverrunCount::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int64uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeNeighborTableListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    new MTRThreadNetworkDiagnosticsNeighborTableListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::NeighborTableList::TypeInfo;
            auto successFn = Callback<ThreadNetworkDiagnosticsNeighborTableListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeNeighborTableListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRThreadNetworkDiagnosticsNeighborTableListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::NeighborTableList::TypeInfo;
            auto successFn = Callback<ThreadNetworkDiagnosticsNeighborTableListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRThreadNetworkDiagnosticsNeighborTableListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeNeighborTableListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRThreadNetworkDiagnosticsNeighborTableListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::NeighborTableList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<ThreadNetworkDiagnosticsNeighborTableListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeRouteTableListWithCompletionHandler:(void (^)(
                                                             NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRThreadNetworkDiagnosticsRouteTableListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::RouteTableList::TypeInfo;
            auto successFn = Callback<ThreadNetworkDiagnosticsRouteTableListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeRouteTableListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRThreadNetworkDiagnosticsRouteTableListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::RouteTableList::TypeInfo;
            auto successFn = Callback<ThreadNetworkDiagnosticsRouteTableListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRThreadNetworkDiagnosticsRouteTableListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeRouteTableListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRThreadNetworkDiagnosticsRouteTableListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::RouteTableList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<ThreadNetworkDiagnosticsRouteTableListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributePartitionIdWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::PartitionId::TypeInfo;
            auto successFn = Callback<NullableInt32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributePartitionIdWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::PartitionId::TypeInfo;
            auto successFn = Callback<NullableInt32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributePartitionIdWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::PartitionId::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeWeightingWithCompletionHandler:(void (^)(
                                                        NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::Weighting::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeWeightingWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::Weighting::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeWeightingWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::Weighting::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeDataVersionWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::DataVersion::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeDataVersionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::DataVersion::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeDataVersionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::DataVersion::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeStableDataVersionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::StableDataVersion::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeStableDataVersionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::StableDataVersion::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeStableDataVersionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::StableDataVersion::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeLeaderRouterIdWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::LeaderRouterId::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeLeaderRouterIdWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::LeaderRouterId::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeLeaderRouterIdWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::LeaderRouterId::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeDetachedRoleCountWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::DetachedRoleCount::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeDetachedRoleCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::DetachedRoleCount::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeDetachedRoleCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::DetachedRoleCount::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeChildRoleCountWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::ChildRoleCount::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeChildRoleCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::ChildRoleCount::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeChildRoleCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::ChildRoleCount::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeRouterRoleCountWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::RouterRoleCount::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeRouterRoleCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::RouterRoleCount::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeRouterRoleCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::RouterRoleCount::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeLeaderRoleCountWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::LeaderRoleCount::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeLeaderRoleCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::LeaderRoleCount::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeLeaderRoleCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::LeaderRoleCount::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeAttachAttemptCountWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                 NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::AttachAttemptCount::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAttachAttemptCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                maxInterval:(NSNumber * _Nonnull)maxInterval
                                                     params:(MTRSubscribeParams * _Nullable)params
                                    subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                              reportHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::AttachAttemptCount::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAttachAttemptCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                        completionHandler:
                                            (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::AttachAttemptCount::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributePartitionIdChangeCountWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::PartitionIdChangeCount::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributePartitionIdChangeCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                                         params:(MTRSubscribeParams * _Nullable)params
                                        subscriptionEstablished:
                                            (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                  reportHandler:
                                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::PartitionIdChangeCount::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributePartitionIdChangeCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                            completionHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::PartitionIdChangeCount::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeBetterPartitionAttachAttemptCountWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                                NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::BetterPartitionAttachAttemptCount::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeBetterPartitionAttachAttemptCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                    params:(MTRSubscribeParams * _Nullable)params
                                                   subscriptionEstablished:
                                                       (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                             reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                               NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::BetterPartitionAttachAttemptCount::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeBetterPartitionAttachAttemptCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                                endpoint:(NSNumber *)endpoint
                                                                   queue:(dispatch_queue_t)queue
                                                       completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                             NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::BetterPartitionAttachAttemptCount::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeParentChangeCountWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::ParentChangeCount::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeParentChangeCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::ParentChangeCount::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeParentChangeCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::ParentChangeCount::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeTxTotalCountWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxTotalCount::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeTxTotalCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxTotalCount::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeTxTotalCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxTotalCount::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeTxUnicastCountWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxUnicastCount::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeTxUnicastCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxUnicastCount::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeTxUnicastCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxUnicastCount::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeTxBroadcastCountWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxBroadcastCount::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeTxBroadcastCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                              maxInterval:(NSNumber * _Nonnull)maxInterval
                                                   params:(MTRSubscribeParams * _Nullable)params
                                  subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                            reportHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxBroadcastCount::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeTxBroadcastCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxBroadcastCount::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeTxAckRequestedCountWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxAckRequestedCount::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeTxAckRequestedCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxAckRequestedCount::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeTxAckRequestedCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxAckRequestedCount::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeTxAckedCountWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxAckedCount::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeTxAckedCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxAckedCount::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeTxAckedCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxAckedCount::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeTxNoAckRequestedCountWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                    NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxNoAckRequestedCount::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeTxNoAckRequestedCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                   maxInterval:(NSNumber * _Nonnull)maxInterval
                                                        params:(MTRSubscribeParams * _Nullable)params
                                       subscriptionEstablished:
                                           (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                 reportHandler:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxNoAckRequestedCount::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeTxNoAckRequestedCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                           completionHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxNoAckRequestedCount::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeTxDataCountWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxDataCount::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeTxDataCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxDataCount::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeTxDataCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxDataCount::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeTxDataPollCountWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxDataPollCount::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeTxDataPollCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxDataPollCount::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeTxDataPollCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxDataPollCount::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeTxBeaconCountWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxBeaconCount::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeTxBeaconCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxBeaconCount::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeTxBeaconCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxBeaconCount::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeTxBeaconRequestCountWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxBeaconRequestCount::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeTxBeaconRequestCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxBeaconRequestCount::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeTxBeaconRequestCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxBeaconRequestCount::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeTxOtherCountWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxOtherCount::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeTxOtherCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxOtherCount::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeTxOtherCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxOtherCount::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeTxRetryCountWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxRetryCount::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeTxRetryCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxRetryCount::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeTxRetryCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxRetryCount::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeTxDirectMaxRetryExpiryCountWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                          NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxDirectMaxRetryExpiryCount::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeTxDirectMaxRetryExpiryCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                                              params:(MTRSubscribeParams * _Nullable)params
                                             subscriptionEstablished:
                                                 (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                       reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxDirectMaxRetryExpiryCount::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeTxDirectMaxRetryExpiryCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                          endpoint:(NSNumber *)endpoint
                                                             queue:(dispatch_queue_t)queue
                                                 completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxDirectMaxRetryExpiryCount::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeTxIndirectMaxRetryExpiryCountWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                            NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxIndirectMaxRetryExpiryCount::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeTxIndirectMaxRetryExpiryCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                params:(MTRSubscribeParams * _Nullable)params
                                               subscriptionEstablished:
                                                   (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                         reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxIndirectMaxRetryExpiryCount::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeTxIndirectMaxRetryExpiryCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                            endpoint:(NSNumber *)endpoint
                                                               queue:(dispatch_queue_t)queue
                                                   completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxIndirectMaxRetryExpiryCount::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeTxErrCcaCountWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxErrCcaCount::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeTxErrCcaCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxErrCcaCount::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeTxErrCcaCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxErrCcaCount::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeTxErrAbortCountWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxErrAbortCount::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeTxErrAbortCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxErrAbortCount::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeTxErrAbortCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxErrAbortCount::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeTxErrBusyChannelCountWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                    NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxErrBusyChannelCount::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeTxErrBusyChannelCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                   maxInterval:(NSNumber * _Nonnull)maxInterval
                                                        params:(MTRSubscribeParams * _Nullable)params
                                       subscriptionEstablished:
                                           (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                 reportHandler:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxErrBusyChannelCount::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeTxErrBusyChannelCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                           completionHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::TxErrBusyChannelCount::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeRxTotalCountWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxTotalCount::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeRxTotalCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxTotalCount::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeRxTotalCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxTotalCount::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeRxUnicastCountWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxUnicastCount::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeRxUnicastCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxUnicastCount::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeRxUnicastCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxUnicastCount::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeRxBroadcastCountWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxBroadcastCount::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeRxBroadcastCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                              maxInterval:(NSNumber * _Nonnull)maxInterval
                                                   params:(MTRSubscribeParams * _Nullable)params
                                  subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                            reportHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxBroadcastCount::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeRxBroadcastCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxBroadcastCount::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeRxDataCountWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxDataCount::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeRxDataCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxDataCount::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeRxDataCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxDataCount::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeRxDataPollCountWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxDataPollCount::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeRxDataPollCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxDataPollCount::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeRxDataPollCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxDataPollCount::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeRxBeaconCountWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxBeaconCount::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeRxBeaconCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxBeaconCount::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeRxBeaconCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxBeaconCount::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeRxBeaconRequestCountWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxBeaconRequestCount::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeRxBeaconRequestCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxBeaconRequestCount::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeRxBeaconRequestCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxBeaconRequestCount::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeRxOtherCountWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxOtherCount::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeRxOtherCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxOtherCount::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeRxOtherCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxOtherCount::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeRxAddressFilteredCountWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxAddressFilteredCount::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeRxAddressFilteredCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                                         params:(MTRSubscribeParams * _Nullable)params
                                        subscriptionEstablished:
                                            (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                  reportHandler:
                                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxAddressFilteredCount::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeRxAddressFilteredCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                            completionHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxAddressFilteredCount::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeRxDestAddrFilteredCountWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxDestAddrFilteredCount::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeRxDestAddrFilteredCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                     maxInterval:(NSNumber * _Nonnull)maxInterval
                                                          params:(MTRSubscribeParams * _Nullable)params
                                         subscriptionEstablished:
                                             (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                   reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxDestAddrFilteredCount::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeRxDestAddrFilteredCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                             completionHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxDestAddrFilteredCount::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeRxDuplicatedCountWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxDuplicatedCount::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeRxDuplicatedCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxDuplicatedCount::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeRxDuplicatedCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxDuplicatedCount::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeRxErrNoFrameCountWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxErrNoFrameCount::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeRxErrNoFrameCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxErrNoFrameCount::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeRxErrNoFrameCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxErrNoFrameCount::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeRxErrUnknownNeighborCountWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxErrUnknownNeighborCount::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeRxErrUnknownNeighborCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                                            params:(MTRSubscribeParams * _Nullable)params
                                           subscriptionEstablished:
                                               (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                     reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxErrUnknownNeighborCount::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeRxErrUnknownNeighborCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                        endpoint:(NSNumber *)endpoint
                                                           queue:(dispatch_queue_t)queue
                                               completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxErrUnknownNeighborCount::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeRxErrInvalidSrcAddrCountWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxErrInvalidSrcAddrCount::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeRxErrInvalidSrcAddrCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                                           params:(MTRSubscribeParams * _Nullable)params
                                          subscriptionEstablished:
                                              (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                    reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxErrInvalidSrcAddrCount::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeRxErrInvalidSrcAddrCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                       endpoint:(NSNumber *)endpoint
                                                          queue:(dispatch_queue_t)queue
                                              completionHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxErrInvalidSrcAddrCount::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeRxErrSecCountWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxErrSecCount::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeRxErrSecCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxErrSecCount::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeRxErrSecCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxErrSecCount::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeRxErrFcsCountWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxErrFcsCount::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeRxErrFcsCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxErrFcsCount::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeRxErrFcsCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxErrFcsCount::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeRxErrOtherCountWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxErrOtherCount::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeRxErrOtherCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxErrOtherCount::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeRxErrOtherCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::RxErrOtherCount::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeActiveTimestampWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRNullableInt64uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::ActiveTimestamp::TypeInfo;
            auto successFn = Callback<NullableInt64uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeActiveTimestampWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt64uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::ActiveTimestamp::TypeInfo;
            auto successFn = Callback<NullableInt64uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt64uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeActiveTimestampWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt64uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::ActiveTimestamp::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt64uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributePendingTimestampWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    new MTRNullableInt64uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::PendingTimestamp::TypeInfo;
            auto successFn = Callback<NullableInt64uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributePendingTimestampWithMinInterval:(NSNumber * _Nonnull)minInterval
                                              maxInterval:(NSNumber * _Nonnull)maxInterval
                                                   params:(MTRSubscribeParams * _Nullable)params
                                  subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                            reportHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt64uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::PendingTimestamp::TypeInfo;
            auto successFn = Callback<NullableInt64uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt64uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributePendingTimestampWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt64uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::PendingTimestamp::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt64uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeDelayWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::Delay::TypeInfo;
            auto successFn = Callback<NullableInt32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeDelayWithMinInterval:(NSNumber * _Nonnull)minInterval
                                   maxInterval:(NSNumber * _Nonnull)maxInterval
                                        params:(MTRSubscribeParams * _Nullable)params
                       subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::Delay::TypeInfo;
            auto successFn = Callback<NullableInt32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeDelayWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                    endpoint:(NSNumber *)endpoint
                                       queue:(dispatch_queue_t)queue
                           completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::Delay::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeSecurityPolicyWithCompletionHandler:
    (void (^)(MTRThreadNetworkDiagnosticsClusterSecurityPolicy * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRThreadNetworkDiagnosticsSecurityPolicyStructAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::SecurityPolicy::TypeInfo;
            auto successFn = Callback<ThreadNetworkDiagnosticsSecurityPolicyStructAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeSecurityPolicyWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(MTRThreadNetworkDiagnosticsClusterSecurityPolicy * _Nullable value,
                                                  NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRThreadNetworkDiagnosticsSecurityPolicyStructAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::SecurityPolicy::TypeInfo;
            auto successFn = Callback<ThreadNetworkDiagnosticsSecurityPolicyStructAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRThreadNetworkDiagnosticsSecurityPolicyStructAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeSecurityPolicyWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:(void (^)(MTRThreadNetworkDiagnosticsClusterSecurityPolicy * _Nullable value,
                                                          NSError * _Nullable error))completionHandler
{
    new MTRThreadNetworkDiagnosticsSecurityPolicyStructAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::SecurityPolicy::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<ThreadNetworkDiagnosticsSecurityPolicyStructAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeChannelMaskWithCompletionHandler:(void (^)(
                                                          NSData * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableOctetStringAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::ChannelMask::TypeInfo;
            auto successFn = Callback<NullableOctetStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeChannelMaskWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSData * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableOctetStringAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::ChannelMask::TypeInfo;
            auto successFn = Callback<NullableOctetStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableOctetStringAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeChannelMaskWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:(void (^)(NSData * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableOctetStringAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::ChannelMask::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableOctetStringAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeOperationalDatasetComponentsWithCompletionHandler:
    (void (^)(MTRThreadNetworkDiagnosticsClusterOperationalDatasetComponents * _Nullable value,
        NSError * _Nullable error))completionHandler
{
    new MTRThreadNetworkDiagnosticsOperationalDatasetComponentsStructAttributeCallbackBridge(self.callbackQueue, self.device,
        completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::OperationalDatasetComponents::TypeInfo;
            auto successFn
                = Callback<ThreadNetworkDiagnosticsOperationalDatasetComponentsStructAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)
    subscribeAttributeOperationalDatasetComponentsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                                           params:(MTRSubscribeParams * _Nullable)params
                                          subscriptionEstablished:
                                              (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                    reportHandler:
                                                        (void (^)(
                                                            MTRThreadNetworkDiagnosticsClusterOperationalDatasetComponents * _Nullable value,
                                                            NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRThreadNetworkDiagnosticsOperationalDatasetComponentsStructAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::OperationalDatasetComponents::TypeInfo;
            auto successFn
                = Callback<ThreadNetworkDiagnosticsOperationalDatasetComponentsStructAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRThreadNetworkDiagnosticsOperationalDatasetComponentsStructAttributeCallbackSubscriptionBridge::
                    OnSubscriptionEstablished,
                nil, params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)
    readAttributeOperationalDatasetComponentsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                       endpoint:(NSNumber *)endpoint
                                                          queue:(dispatch_queue_t)queue
                                              completionHandler:
                                                  (void (^)(
                                                      MTRThreadNetworkDiagnosticsClusterOperationalDatasetComponents * _Nullable value,
                                                      NSError * _Nullable error))completionHandler
{
    new MTRThreadNetworkDiagnosticsOperationalDatasetComponentsStructAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::OperationalDatasetComponents::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn
                    = Callback<ThreadNetworkDiagnosticsOperationalDatasetComponentsStructAttributeCallback>::FromCancelable(
                        success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeActiveNetworkFaultsListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                      NSError * _Nullable error))completionHandler
{
    new MTRThreadNetworkDiagnosticsActiveNetworkFaultsListListAttributeCallbackBridge(self.callbackQueue, self.device,
        completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::ActiveNetworkFaultsList::TypeInfo;
            auto successFn
                = Callback<ThreadNetworkDiagnosticsActiveNetworkFaultsListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeActiveNetworkFaultsListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                     maxInterval:(NSNumber * _Nonnull)maxInterval
                                                          params:(MTRSubscribeParams * _Nullable)params
                                         subscriptionEstablished:
                                             (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                   reportHandler:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRThreadNetworkDiagnosticsActiveNetworkFaultsListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::ActiveNetworkFaultsList::TypeInfo;
            auto successFn
                = Callback<ThreadNetworkDiagnosticsActiveNetworkFaultsListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRThreadNetworkDiagnosticsActiveNetworkFaultsListListAttributeCallbackSubscriptionBridge::
                    OnSubscriptionEstablished,
                nil, params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeActiveNetworkFaultsListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                             completionHandler:
                                                 (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRThreadNetworkDiagnosticsActiveNetworkFaultsListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::ActiveNetworkFaultsList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn
                    = Callback<ThreadNetworkDiagnosticsActiveNetworkFaultsListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRThreadNetworkDiagnosticsGeneratedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device,
        completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<ThreadNetworkDiagnosticsGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRThreadNetworkDiagnosticsGeneratedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<ThreadNetworkDiagnosticsGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRThreadNetworkDiagnosticsGeneratedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished,
                nil, params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRThreadNetworkDiagnosticsGeneratedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn
                    = Callback<ThreadNetworkDiagnosticsGeneratedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRThreadNetworkDiagnosticsAcceptedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device,
        completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<ThreadNetworkDiagnosticsAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRThreadNetworkDiagnosticsAcceptedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<ThreadNetworkDiagnosticsAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRThreadNetworkDiagnosticsAcceptedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished,
                nil, params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRThreadNetworkDiagnosticsAcceptedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn
                    = Callback<ThreadNetworkDiagnosticsAcceptedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRThreadNetworkDiagnosticsAttributeListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<ThreadNetworkDiagnosticsAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRThreadNetworkDiagnosticsAttributeListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<ThreadNetworkDiagnosticsAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRThreadNetworkDiagnosticsAttributeListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRThreadNetworkDiagnosticsAttributeListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThreadNetworkDiagnostics::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<ThreadNetworkDiagnosticsAttributeListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::FeatureMap::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThreadNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ThreadNetworkDiagnostics::Attributes::ClusterRevision::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

@end

@implementation MTRBaseClusterWiFiNetworkDiagnostics

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = endpoint;
    }
    return self;
}

- (void)resetCountsWithCompletionHandler:(StatusCompletion)completionHandler
{
    [self resetCountsWithParams:nil completionHandler:completionHandler];
}
- (void)resetCountsWithParams:(MTRWiFiNetworkDiagnosticsClusterResetCountsParams * _Nullable)params
            completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            WiFiNetworkDiagnostics::Commands::ResetCounts::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::WiFiNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)readAttributeBssidWithCompletionHandler:(void (^)(NSData * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableOctetStringAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = WiFiNetworkDiagnostics::Attributes::Bssid::TypeInfo;
            auto successFn = Callback<NullableOctetStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::WiFiNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeBssidWithMinInterval:(NSNumber * _Nonnull)minInterval
                                   maxInterval:(NSNumber * _Nonnull)maxInterval
                                        params:(MTRSubscribeParams * _Nullable)params
                       subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                 reportHandler:(void (^)(NSData * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableOctetStringAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = WiFiNetworkDiagnostics::Attributes::Bssid::TypeInfo;
            auto successFn = Callback<NullableOctetStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::WiFiNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableOctetStringAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeBssidWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                    endpoint:(NSNumber *)endpoint
                                       queue:(dispatch_queue_t)queue
                           completionHandler:(void (^)(NSData * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableOctetStringAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = WiFiNetworkDiagnostics::Attributes::Bssid::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableOctetStringAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeSecurityTypeWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableWiFiNetworkDiagnosticsClusterSecurityTypeAttributeCallbackBridge(self.callbackQueue, self.device,
        completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = WiFiNetworkDiagnostics::Attributes::SecurityType::TypeInfo;
            auto successFn = Callback<NullableWiFiNetworkDiagnosticsClusterSecurityTypeAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::WiFiNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeSecurityTypeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableWiFiNetworkDiagnosticsClusterSecurityTypeAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = WiFiNetworkDiagnostics::Attributes::SecurityType::TypeInfo;
            auto successFn = Callback<NullableWiFiNetworkDiagnosticsClusterSecurityTypeAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::WiFiNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableWiFiNetworkDiagnosticsClusterSecurityTypeAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished,
                nil, params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeSecurityTypeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableWiFiNetworkDiagnosticsClusterSecurityTypeAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WiFiNetworkDiagnostics::Attributes::SecurityType::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn
                    = Callback<NullableWiFiNetworkDiagnosticsClusterSecurityTypeAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeWiFiVersionWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableWiFiNetworkDiagnosticsClusterWiFiVersionTypeAttributeCallbackBridge(self.callbackQueue, self.device,
        completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = WiFiNetworkDiagnostics::Attributes::WiFiVersion::TypeInfo;
            auto successFn
                = Callback<NullableWiFiNetworkDiagnosticsClusterWiFiVersionTypeAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::WiFiNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeWiFiVersionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableWiFiNetworkDiagnosticsClusterWiFiVersionTypeAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = WiFiNetworkDiagnostics::Attributes::WiFiVersion::TypeInfo;
            auto successFn
                = Callback<NullableWiFiNetworkDiagnosticsClusterWiFiVersionTypeAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::WiFiNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableWiFiNetworkDiagnosticsClusterWiFiVersionTypeAttributeCallbackSubscriptionBridge::
                    OnSubscriptionEstablished,
                nil, params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeWiFiVersionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableWiFiNetworkDiagnosticsClusterWiFiVersionTypeAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WiFiNetworkDiagnostics::Attributes::WiFiVersion::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn
                    = Callback<NullableWiFiNetworkDiagnosticsClusterWiFiVersionTypeAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeChannelNumberWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = WiFiNetworkDiagnostics::Attributes::ChannelNumber::TypeInfo;
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::WiFiNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeChannelNumberWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = WiFiNetworkDiagnostics::Attributes::ChannelNumber::TypeInfo;
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::WiFiNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeChannelNumberWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = WiFiNetworkDiagnostics::Attributes::ChannelNumber::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeRssiWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = WiFiNetworkDiagnostics::Attributes::Rssi::TypeInfo;
            auto successFn = Callback<NullableInt8sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::WiFiNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeRssiWithMinInterval:(NSNumber * _Nonnull)minInterval
                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                       params:(MTRSubscribeParams * _Nullable)params
                      subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt8sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = WiFiNetworkDiagnostics::Attributes::Rssi::TypeInfo;
            auto successFn = Callback<NullableInt8sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::WiFiNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt8sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeRssiWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                   endpoint:(NSNumber *)endpoint
                                      queue:(dispatch_queue_t)queue
                          completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = WiFiNetworkDiagnostics::Attributes::Rssi::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt8sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeBeaconLostCountWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRNullableInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = WiFiNetworkDiagnostics::Attributes::BeaconLostCount::TypeInfo;
            auto successFn = Callback<NullableInt32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::WiFiNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeBeaconLostCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = WiFiNetworkDiagnostics::Attributes::BeaconLostCount::TypeInfo;
            auto successFn = Callback<NullableInt32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::WiFiNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeBeaconLostCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = WiFiNetworkDiagnostics::Attributes::BeaconLostCount::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeBeaconRxCountWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = WiFiNetworkDiagnostics::Attributes::BeaconRxCount::TypeInfo;
            auto successFn = Callback<NullableInt32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::WiFiNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeBeaconRxCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = WiFiNetworkDiagnostics::Attributes::BeaconRxCount::TypeInfo;
            auto successFn = Callback<NullableInt32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::WiFiNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeBeaconRxCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = WiFiNetworkDiagnostics::Attributes::BeaconRxCount::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributePacketMulticastRxCountWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completionHandler
{
    new MTRNullableInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = WiFiNetworkDiagnostics::Attributes::PacketMulticastRxCount::TypeInfo;
            auto successFn = Callback<NullableInt32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::WiFiNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributePacketMulticastRxCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                                         params:(MTRSubscribeParams * _Nullable)params
                                        subscriptionEstablished:
                                            (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                  reportHandler:
                                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = WiFiNetworkDiagnostics::Attributes::PacketMulticastRxCount::TypeInfo;
            auto successFn = Callback<NullableInt32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::WiFiNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributePacketMulticastRxCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                            completionHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = WiFiNetworkDiagnostics::Attributes::PacketMulticastRxCount::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributePacketMulticastTxCountWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completionHandler
{
    new MTRNullableInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = WiFiNetworkDiagnostics::Attributes::PacketMulticastTxCount::TypeInfo;
            auto successFn = Callback<NullableInt32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::WiFiNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributePacketMulticastTxCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                                         params:(MTRSubscribeParams * _Nullable)params
                                        subscriptionEstablished:
                                            (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                  reportHandler:
                                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = WiFiNetworkDiagnostics::Attributes::PacketMulticastTxCount::TypeInfo;
            auto successFn = Callback<NullableInt32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::WiFiNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributePacketMulticastTxCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                            completionHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = WiFiNetworkDiagnostics::Attributes::PacketMulticastTxCount::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributePacketUnicastRxCountWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRNullableInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = WiFiNetworkDiagnostics::Attributes::PacketUnicastRxCount::TypeInfo;
            auto successFn = Callback<NullableInt32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::WiFiNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributePacketUnicastRxCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = WiFiNetworkDiagnostics::Attributes::PacketUnicastRxCount::TypeInfo;
            auto successFn = Callback<NullableInt32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::WiFiNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributePacketUnicastRxCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = WiFiNetworkDiagnostics::Attributes::PacketUnicastRxCount::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributePacketUnicastTxCountWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRNullableInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = WiFiNetworkDiagnostics::Attributes::PacketUnicastTxCount::TypeInfo;
            auto successFn = Callback<NullableInt32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::WiFiNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributePacketUnicastTxCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = WiFiNetworkDiagnostics::Attributes::PacketUnicastTxCount::TypeInfo;
            auto successFn = Callback<NullableInt32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::WiFiNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributePacketUnicastTxCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = WiFiNetworkDiagnostics::Attributes::PacketUnicastTxCount::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeCurrentMaxRateWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    new MTRNullableInt64uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = WiFiNetworkDiagnostics::Attributes::CurrentMaxRate::TypeInfo;
            auto successFn = Callback<NullableInt64uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::WiFiNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeCurrentMaxRateWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt64uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = WiFiNetworkDiagnostics::Attributes::CurrentMaxRate::TypeInfo;
            auto successFn = Callback<NullableInt64uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::WiFiNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt64uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeCurrentMaxRateWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt64uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = WiFiNetworkDiagnostics::Attributes::CurrentMaxRate::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt64uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeOverrunCountWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt64uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = WiFiNetworkDiagnostics::Attributes::OverrunCount::TypeInfo;
            auto successFn = Callback<NullableInt64uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::WiFiNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeOverrunCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt64uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = WiFiNetworkDiagnostics::Attributes::OverrunCount::TypeInfo;
            auto successFn = Callback<NullableInt64uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::WiFiNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt64uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeOverrunCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt64uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = WiFiNetworkDiagnostics::Attributes::OverrunCount::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt64uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRWiFiNetworkDiagnosticsGeneratedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = WiFiNetworkDiagnostics::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<WiFiNetworkDiagnosticsGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::WiFiNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRWiFiNetworkDiagnosticsGeneratedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = WiFiNetworkDiagnostics::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<WiFiNetworkDiagnosticsGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::WiFiNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRWiFiNetworkDiagnosticsGeneratedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished,
                nil, params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRWiFiNetworkDiagnosticsGeneratedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WiFiNetworkDiagnostics::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<WiFiNetworkDiagnosticsGeneratedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRWiFiNetworkDiagnosticsAcceptedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = WiFiNetworkDiagnostics::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<WiFiNetworkDiagnosticsAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::WiFiNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRWiFiNetworkDiagnosticsAcceptedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = WiFiNetworkDiagnostics::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<WiFiNetworkDiagnosticsAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::WiFiNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRWiFiNetworkDiagnosticsAcceptedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRWiFiNetworkDiagnosticsAcceptedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WiFiNetworkDiagnostics::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<WiFiNetworkDiagnosticsAcceptedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRWiFiNetworkDiagnosticsAttributeListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = WiFiNetworkDiagnostics::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<WiFiNetworkDiagnosticsAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::WiFiNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRWiFiNetworkDiagnosticsAttributeListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = WiFiNetworkDiagnostics::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<WiFiNetworkDiagnosticsAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::WiFiNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRWiFiNetworkDiagnosticsAttributeListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRWiFiNetworkDiagnosticsAttributeListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WiFiNetworkDiagnostics::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<WiFiNetworkDiagnosticsAttributeListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = WiFiNetworkDiagnostics::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::WiFiNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = WiFiNetworkDiagnostics::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::WiFiNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = WiFiNetworkDiagnostics::Attributes::FeatureMap::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = WiFiNetworkDiagnostics::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::WiFiNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = WiFiNetworkDiagnostics::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::WiFiNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = WiFiNetworkDiagnostics::Attributes::ClusterRevision::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

@end

@implementation MTRBaseClusterEthernetNetworkDiagnostics

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = endpoint;
    }
    return self;
}

- (void)resetCountsWithCompletionHandler:(StatusCompletion)completionHandler
{
    [self resetCountsWithParams:nil completionHandler:completionHandler];
}
- (void)resetCountsWithParams:(MTREthernetNetworkDiagnosticsClusterResetCountsParams * _Nullable)params
            completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            EthernetNetworkDiagnostics::Commands::ResetCounts::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::EthernetNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)readAttributePHYRateWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableEthernetNetworkDiagnosticsClusterPHYRateTypeAttributeCallbackBridge(self.callbackQueue, self.device,
        completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = EthernetNetworkDiagnostics::Attributes::PHYRate::TypeInfo;
            auto successFn
                = Callback<NullableEthernetNetworkDiagnosticsClusterPHYRateTypeAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::EthernetNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributePHYRateWithMinInterval:(NSNumber * _Nonnull)minInterval
                                     maxInterval:(NSNumber * _Nonnull)maxInterval
                                          params:(MTRSubscribeParams * _Nullable)params
                         subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                   reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableEthernetNetworkDiagnosticsClusterPHYRateTypeAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = EthernetNetworkDiagnostics::Attributes::PHYRate::TypeInfo;
            auto successFn
                = Callback<NullableEthernetNetworkDiagnosticsClusterPHYRateTypeAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::EthernetNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableEthernetNetworkDiagnosticsClusterPHYRateTypeAttributeCallbackSubscriptionBridge::
                    OnSubscriptionEstablished,
                nil, params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributePHYRateWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                      endpoint:(NSNumber *)endpoint
                                         queue:(dispatch_queue_t)queue
                             completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableEthernetNetworkDiagnosticsClusterPHYRateTypeAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = EthernetNetworkDiagnostics::Attributes::PHYRate::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn
                    = Callback<NullableEthernetNetworkDiagnosticsClusterPHYRateTypeAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFullDuplexWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableBooleanAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = EthernetNetworkDiagnostics::Attributes::FullDuplex::TypeInfo;
            auto successFn = Callback<NullableBooleanAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::EthernetNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeFullDuplexWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableBooleanAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = EthernetNetworkDiagnostics::Attributes::FullDuplex::TypeInfo;
            auto successFn = Callback<NullableBooleanAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::EthernetNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableBooleanAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeFullDuplexWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableBooleanAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = EthernetNetworkDiagnostics::Attributes::FullDuplex::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableBooleanAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributePacketRxCountWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt64uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = EthernetNetworkDiagnostics::Attributes::PacketRxCount::TypeInfo;
            auto successFn = Callback<Int64uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::EthernetNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributePacketRxCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt64uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = EthernetNetworkDiagnostics::Attributes::PacketRxCount::TypeInfo;
            auto successFn = Callback<Int64uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::EthernetNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt64uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributePacketRxCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt64uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = EthernetNetworkDiagnostics::Attributes::PacketRxCount::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int64uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributePacketTxCountWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt64uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = EthernetNetworkDiagnostics::Attributes::PacketTxCount::TypeInfo;
            auto successFn = Callback<Int64uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::EthernetNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributePacketTxCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt64uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = EthernetNetworkDiagnostics::Attributes::PacketTxCount::TypeInfo;
            auto successFn = Callback<Int64uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::EthernetNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt64uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributePacketTxCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt64uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = EthernetNetworkDiagnostics::Attributes::PacketTxCount::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int64uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeTxErrCountWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt64uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = EthernetNetworkDiagnostics::Attributes::TxErrCount::TypeInfo;
            auto successFn = Callback<Int64uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::EthernetNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeTxErrCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt64uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = EthernetNetworkDiagnostics::Attributes::TxErrCount::TypeInfo;
            auto successFn = Callback<Int64uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::EthernetNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt64uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeTxErrCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt64uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = EthernetNetworkDiagnostics::Attributes::TxErrCount::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int64uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeCollisionCountWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    new MTRInt64uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = EthernetNetworkDiagnostics::Attributes::CollisionCount::TypeInfo;
            auto successFn = Callback<Int64uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::EthernetNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeCollisionCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt64uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = EthernetNetworkDiagnostics::Attributes::CollisionCount::TypeInfo;
            auto successFn = Callback<Int64uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::EthernetNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt64uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeCollisionCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt64uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = EthernetNetworkDiagnostics::Attributes::CollisionCount::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int64uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeOverrunCountWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt64uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = EthernetNetworkDiagnostics::Attributes::OverrunCount::TypeInfo;
            auto successFn = Callback<Int64uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::EthernetNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeOverrunCountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt64uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = EthernetNetworkDiagnostics::Attributes::OverrunCount::TypeInfo;
            auto successFn = Callback<Int64uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::EthernetNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt64uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeOverrunCountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt64uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = EthernetNetworkDiagnostics::Attributes::OverrunCount::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int64uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeCarrierDetectWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableBooleanAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = EthernetNetworkDiagnostics::Attributes::CarrierDetect::TypeInfo;
            auto successFn = Callback<NullableBooleanAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::EthernetNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeCarrierDetectWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableBooleanAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = EthernetNetworkDiagnostics::Attributes::CarrierDetect::TypeInfo;
            auto successFn = Callback<NullableBooleanAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::EthernetNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableBooleanAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeCarrierDetectWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableBooleanAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = EthernetNetworkDiagnostics::Attributes::CarrierDetect::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableBooleanAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeTimeSinceResetWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    new MTRInt64uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = EthernetNetworkDiagnostics::Attributes::TimeSinceReset::TypeInfo;
            auto successFn = Callback<Int64uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::EthernetNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeTimeSinceResetWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt64uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = EthernetNetworkDiagnostics::Attributes::TimeSinceReset::TypeInfo;
            auto successFn = Callback<Int64uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::EthernetNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt64uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeTimeSinceResetWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt64uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = EthernetNetworkDiagnostics::Attributes::TimeSinceReset::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int64uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTREthernetNetworkDiagnosticsGeneratedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device,
        completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = EthernetNetworkDiagnostics::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<EthernetNetworkDiagnosticsGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::EthernetNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTREthernetNetworkDiagnosticsGeneratedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = EthernetNetworkDiagnostics::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<EthernetNetworkDiagnosticsGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::EthernetNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTREthernetNetworkDiagnosticsGeneratedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished,
                nil, params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTREthernetNetworkDiagnosticsGeneratedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = EthernetNetworkDiagnostics::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn
                    = Callback<EthernetNetworkDiagnosticsGeneratedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTREthernetNetworkDiagnosticsAcceptedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device,
        completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = EthernetNetworkDiagnostics::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<EthernetNetworkDiagnosticsAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::EthernetNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTREthernetNetworkDiagnosticsAcceptedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = EthernetNetworkDiagnostics::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<EthernetNetworkDiagnosticsAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::EthernetNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTREthernetNetworkDiagnosticsAcceptedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished,
                nil, params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTREthernetNetworkDiagnosticsAcceptedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = EthernetNetworkDiagnostics::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn
                    = Callback<EthernetNetworkDiagnosticsAcceptedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTREthernetNetworkDiagnosticsAttributeListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = EthernetNetworkDiagnostics::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<EthernetNetworkDiagnosticsAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::EthernetNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTREthernetNetworkDiagnosticsAttributeListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = EthernetNetworkDiagnostics::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<EthernetNetworkDiagnosticsAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::EthernetNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTREthernetNetworkDiagnosticsAttributeListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTREthernetNetworkDiagnosticsAttributeListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = EthernetNetworkDiagnostics::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<EthernetNetworkDiagnosticsAttributeListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = EthernetNetworkDiagnostics::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::EthernetNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = EthernetNetworkDiagnostics::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::EthernetNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = EthernetNetworkDiagnostics::Attributes::FeatureMap::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = EthernetNetworkDiagnostics::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::EthernetNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = EthernetNetworkDiagnostics::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::EthernetNetworkDiagnosticsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = EthernetNetworkDiagnostics::Attributes::ClusterRevision::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

@end

@implementation MTRBaseClusterBridgedDeviceBasic

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = endpoint;
    }
    return self;
}

- (void)readAttributeVendorNameWithCompletionHandler:(void (^)(
                                                         NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BridgedDeviceBasic::Attributes::VendorName::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BridgedDeviceBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeVendorNameWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRCharStringAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BridgedDeviceBasic::Attributes::VendorName::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BridgedDeviceBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRCharStringAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeVendorNameWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = BridgedDeviceBasic::Attributes::VendorName::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeVendorIDWithCompletionHandler:(void (^)(
                                                       NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRVendorIdAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BridgedDeviceBasic::Attributes::VendorID::TypeInfo;
            auto successFn = Callback<VendorIdAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BridgedDeviceBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeVendorIDWithMinInterval:(NSNumber * _Nonnull)minInterval
                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                           params:(MTRSubscribeParams * _Nullable)params
                          subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRVendorIdAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BridgedDeviceBasic::Attributes::VendorID::TypeInfo;
            auto successFn = Callback<VendorIdAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BridgedDeviceBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRVendorIdAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeVendorIDWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                       endpoint:(NSNumber *)endpoint
                                          queue:(dispatch_queue_t)queue
                              completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRVendorIdAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = BridgedDeviceBasic::Attributes::VendorID::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<VendorIdAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeProductNameWithCompletionHandler:(void (^)(
                                                          NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BridgedDeviceBasic::Attributes::ProductName::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BridgedDeviceBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeProductNameWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRCharStringAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BridgedDeviceBasic::Attributes::ProductName::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BridgedDeviceBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRCharStringAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeProductNameWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = BridgedDeviceBasic::Attributes::ProductName::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeNodeLabelWithCompletionHandler:(void (^)(
                                                        NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BridgedDeviceBasic::Attributes::NodeLabel::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BridgedDeviceBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeNodeLabelWithValue:(NSString * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeNodeLabelWithValue:(NSString * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeNodeLabelWithValue:(NSString * _Nonnull)value
                                  params:(MTRWriteParams * _Nullable)params
                       completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = BridgedDeviceBasic::Attributes::NodeLabel::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = [self asCharSpan:value];
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BridgedDeviceBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeNodeLabelWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRCharStringAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BridgedDeviceBasic::Attributes::NodeLabel::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BridgedDeviceBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRCharStringAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeNodeLabelWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = BridgedDeviceBasic::Attributes::NodeLabel::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeHardwareVersionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BridgedDeviceBasic::Attributes::HardwareVersion::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BridgedDeviceBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeHardwareVersionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BridgedDeviceBasic::Attributes::HardwareVersion::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BridgedDeviceBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeHardwareVersionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = BridgedDeviceBasic::Attributes::HardwareVersion::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeHardwareVersionStringWithCompletionHandler:(void (^)(NSString * _Nullable value,
                                                                    NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BridgedDeviceBasic::Attributes::HardwareVersionString::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BridgedDeviceBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeHardwareVersionStringWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                   maxInterval:(NSNumber * _Nonnull)maxInterval
                                                        params:(MTRSubscribeParams * _Nullable)params
                                       subscriptionEstablished:
                                           (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                 reportHandler:
                                                     (void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRCharStringAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BridgedDeviceBasic::Attributes::HardwareVersionString::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BridgedDeviceBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRCharStringAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeHardwareVersionStringWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                           completionHandler:
                                               (void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = BridgedDeviceBasic::Attributes::HardwareVersionString::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeSoftwareVersionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BridgedDeviceBasic::Attributes::SoftwareVersion::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BridgedDeviceBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeSoftwareVersionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BridgedDeviceBasic::Attributes::SoftwareVersion::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BridgedDeviceBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeSoftwareVersionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = BridgedDeviceBasic::Attributes::SoftwareVersion::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeSoftwareVersionStringWithCompletionHandler:(void (^)(NSString * _Nullable value,
                                                                    NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BridgedDeviceBasic::Attributes::SoftwareVersionString::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BridgedDeviceBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeSoftwareVersionStringWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                   maxInterval:(NSNumber * _Nonnull)maxInterval
                                                        params:(MTRSubscribeParams * _Nullable)params
                                       subscriptionEstablished:
                                           (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                 reportHandler:
                                                     (void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRCharStringAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BridgedDeviceBasic::Attributes::SoftwareVersionString::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BridgedDeviceBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRCharStringAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeSoftwareVersionStringWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                           completionHandler:
                                               (void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = BridgedDeviceBasic::Attributes::SoftwareVersionString::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeManufacturingDateWithCompletionHandler:(void (^)(NSString * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BridgedDeviceBasic::Attributes::ManufacturingDate::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BridgedDeviceBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeManufacturingDateWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRCharStringAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BridgedDeviceBasic::Attributes::ManufacturingDate::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BridgedDeviceBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRCharStringAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeManufacturingDateWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = BridgedDeviceBasic::Attributes::ManufacturingDate::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributePartNumberWithCompletionHandler:(void (^)(
                                                         NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BridgedDeviceBasic::Attributes::PartNumber::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BridgedDeviceBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributePartNumberWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRCharStringAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BridgedDeviceBasic::Attributes::PartNumber::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BridgedDeviceBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRCharStringAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributePartNumberWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = BridgedDeviceBasic::Attributes::PartNumber::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeProductURLWithCompletionHandler:(void (^)(
                                                         NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BridgedDeviceBasic::Attributes::ProductURL::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BridgedDeviceBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeProductURLWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRCharStringAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BridgedDeviceBasic::Attributes::ProductURL::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BridgedDeviceBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRCharStringAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeProductURLWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = BridgedDeviceBasic::Attributes::ProductURL::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeProductLabelWithCompletionHandler:(void (^)(
                                                           NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BridgedDeviceBasic::Attributes::ProductLabel::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BridgedDeviceBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeProductLabelWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRCharStringAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BridgedDeviceBasic::Attributes::ProductLabel::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BridgedDeviceBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRCharStringAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeProductLabelWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = BridgedDeviceBasic::Attributes::ProductLabel::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeSerialNumberWithCompletionHandler:(void (^)(
                                                           NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BridgedDeviceBasic::Attributes::SerialNumber::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BridgedDeviceBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeSerialNumberWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRCharStringAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BridgedDeviceBasic::Attributes::SerialNumber::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BridgedDeviceBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRCharStringAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeSerialNumberWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = BridgedDeviceBasic::Attributes::SerialNumber::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeReachableWithCompletionHandler:(void (^)(
                                                        NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBooleanAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BridgedDeviceBasic::Attributes::Reachable::TypeInfo;
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BridgedDeviceBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeReachableWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRBooleanAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BridgedDeviceBasic::Attributes::Reachable::TypeInfo;
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BridgedDeviceBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRBooleanAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeReachableWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBooleanAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = BridgedDeviceBasic::Attributes::Reachable::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeUniqueIDWithCompletionHandler:(void (^)(
                                                       NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BridgedDeviceBasic::Attributes::UniqueID::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BridgedDeviceBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeUniqueIDWithMinInterval:(NSNumber * _Nonnull)minInterval
                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                           params:(MTRSubscribeParams * _Nullable)params
                          subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                    reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRCharStringAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BridgedDeviceBasic::Attributes::UniqueID::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BridgedDeviceBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRCharStringAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeUniqueIDWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                       endpoint:(NSNumber *)endpoint
                                          queue:(dispatch_queue_t)queue
                              completionHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = BridgedDeviceBasic::Attributes::UniqueID::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRBridgedDeviceBasicGeneratedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BridgedDeviceBasic::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<BridgedDeviceBasicGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BridgedDeviceBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRBridgedDeviceBasicGeneratedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BridgedDeviceBasic::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<BridgedDeviceBasicGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BridgedDeviceBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRBridgedDeviceBasicGeneratedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBridgedDeviceBasicGeneratedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BridgedDeviceBasic::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<BridgedDeviceBasicGeneratedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRBridgedDeviceBasicAcceptedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BridgedDeviceBasic::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<BridgedDeviceBasicAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BridgedDeviceBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRBridgedDeviceBasicAcceptedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BridgedDeviceBasic::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<BridgedDeviceBasicAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BridgedDeviceBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRBridgedDeviceBasicAcceptedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBridgedDeviceBasicAcceptedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BridgedDeviceBasic::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<BridgedDeviceBasicAcceptedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBridgedDeviceBasicAttributeListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BridgedDeviceBasic::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<BridgedDeviceBasicAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BridgedDeviceBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRBridgedDeviceBasicAttributeListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BridgedDeviceBasic::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<BridgedDeviceBasicAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BridgedDeviceBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRBridgedDeviceBasicAttributeListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBridgedDeviceBasicAttributeListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BridgedDeviceBasic::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<BridgedDeviceBasicAttributeListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BridgedDeviceBasic::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BridgedDeviceBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BridgedDeviceBasic::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BridgedDeviceBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = BridgedDeviceBasic::Attributes::FeatureMap::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BridgedDeviceBasic::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BridgedDeviceBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BridgedDeviceBasic::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BridgedDeviceBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = BridgedDeviceBasic::Attributes::ClusterRevision::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

@end

@implementation MTRBaseClusterSwitch

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = endpoint;
    }
    return self;
}

- (void)readAttributeNumberOfPositionsWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Switch::Attributes::NumberOfPositions::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::SwitchCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeNumberOfPositionsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Switch::Attributes::NumberOfPositions::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::SwitchCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeNumberOfPositionsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Switch::Attributes::NumberOfPositions::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeCurrentPositionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Switch::Attributes::CurrentPosition::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::SwitchCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeCurrentPositionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Switch::Attributes::CurrentPosition::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::SwitchCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeCurrentPositionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Switch::Attributes::CurrentPosition::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeMultiPressMaxWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Switch::Attributes::MultiPressMax::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::SwitchCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeMultiPressMaxWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Switch::Attributes::MultiPressMax::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::SwitchCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeMultiPressMaxWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Switch::Attributes::MultiPressMax::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRSwitchGeneratedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Switch::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<SwitchGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::SwitchCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRSwitchGeneratedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Switch::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<SwitchGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::SwitchCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRSwitchGeneratedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRSwitchGeneratedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Switch::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<SwitchGeneratedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRSwitchAcceptedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Switch::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<SwitchAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::SwitchCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRSwitchAcceptedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Switch::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<SwitchAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::SwitchCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRSwitchAcceptedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRSwitchAcceptedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Switch::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<SwitchAcceptedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRSwitchAttributeListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Switch::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<SwitchAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::SwitchCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRSwitchAttributeListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Switch::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<SwitchAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::SwitchCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRSwitchAttributeListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRSwitchAttributeListListAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Switch::Attributes::AttributeList::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<SwitchAttributeListListAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Switch::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::SwitchCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Switch::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::SwitchCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Switch::Attributes::FeatureMap::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Switch::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::SwitchCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Switch::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::SwitchCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Switch::Attributes::ClusterRevision::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

@end

@implementation MTRBaseClusterAdministratorCommissioning

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = endpoint;
    }
    return self;
}

- (void)openCommissioningWindowWithParams:(MTRAdministratorCommissioningClusterOpenCommissioningWindowParams *)params
                        completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            AdministratorCommissioning::Commands::OpenCommissioningWindow::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            if (!timedInvokeTimeoutMs.HasValue()) {
                timedInvokeTimeoutMs.SetValue(10000);
            }
            request.commissioningTimeout = params.commissioningTimeout.unsignedShortValue;
            request.PAKEVerifier = [self asByteSpan:params.pakeVerifier];
            request.discriminator = params.discriminator.unsignedShortValue;
            request.iterations = params.iterations.unsignedIntValue;
            request.salt = [self asByteSpan:params.salt];

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::AdministratorCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)openBasicCommissioningWindowWithParams:(MTRAdministratorCommissioningClusterOpenBasicCommissioningWindowParams *)params
                             completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            AdministratorCommissioning::Commands::OpenBasicCommissioningWindow::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            if (!timedInvokeTimeoutMs.HasValue()) {
                timedInvokeTimeoutMs.SetValue(10000);
            }
            request.commissioningTimeout = params.commissioningTimeout.unsignedShortValue;

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::AdministratorCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)revokeCommissioningWithCompletionHandler:(StatusCompletion)completionHandler
{
    [self revokeCommissioningWithParams:nil completionHandler:completionHandler];
}
- (void)revokeCommissioningWithParams:(MTRAdministratorCommissioningClusterRevokeCommissioningParams * _Nullable)params
                    completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            AdministratorCommissioning::Commands::RevokeCommissioning::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            if (!timedInvokeTimeoutMs.HasValue()) {
                timedInvokeTimeoutMs.SetValue(10000);
            }

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::AdministratorCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)readAttributeWindowStatusWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = AdministratorCommissioning::Attributes::WindowStatus::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::AdministratorCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeWindowStatusWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = AdministratorCommissioning::Attributes::WindowStatus::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::AdministratorCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeWindowStatusWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = AdministratorCommissioning::Attributes::WindowStatus::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeAdminFabricIndexWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = AdministratorCommissioning::Attributes::AdminFabricIndex::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::AdministratorCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAdminFabricIndexWithMinInterval:(NSNumber * _Nonnull)minInterval
                                              maxInterval:(NSNumber * _Nonnull)maxInterval
                                                   params:(MTRSubscribeParams * _Nullable)params
                                  subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                            reportHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = AdministratorCommissioning::Attributes::AdminFabricIndex::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::AdministratorCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAdminFabricIndexWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = AdministratorCommissioning::Attributes::AdminFabricIndex::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeAdminVendorIdWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = AdministratorCommissioning::Attributes::AdminVendorId::TypeInfo;
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::AdministratorCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAdminVendorIdWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = AdministratorCommissioning::Attributes::AdminVendorId::TypeInfo;
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::AdministratorCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAdminVendorIdWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = AdministratorCommissioning::Attributes::AdminVendorId::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRAdministratorCommissioningGeneratedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device,
        completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = AdministratorCommissioning::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<AdministratorCommissioningGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::AdministratorCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRAdministratorCommissioningGeneratedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = AdministratorCommissioning::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<AdministratorCommissioningGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::AdministratorCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRAdministratorCommissioningGeneratedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished,
                nil, params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRAdministratorCommissioningGeneratedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = AdministratorCommissioning::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn
                    = Callback<AdministratorCommissioningGeneratedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRAdministratorCommissioningAcceptedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device,
        completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = AdministratorCommissioning::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<AdministratorCommissioningAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::AdministratorCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRAdministratorCommissioningAcceptedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = AdministratorCommissioning::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<AdministratorCommissioningAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::AdministratorCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRAdministratorCommissioningAcceptedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished,
                nil, params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRAdministratorCommissioningAcceptedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = AdministratorCommissioning::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn
                    = Callback<AdministratorCommissioningAcceptedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRAdministratorCommissioningAttributeListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = AdministratorCommissioning::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<AdministratorCommissioningAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::AdministratorCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRAdministratorCommissioningAttributeListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = AdministratorCommissioning::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<AdministratorCommissioningAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::AdministratorCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRAdministratorCommissioningAttributeListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRAdministratorCommissioningAttributeListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = AdministratorCommissioning::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<AdministratorCommissioningAttributeListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = AdministratorCommissioning::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::AdministratorCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = AdministratorCommissioning::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::AdministratorCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = AdministratorCommissioning::Attributes::FeatureMap::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = AdministratorCommissioning::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::AdministratorCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = AdministratorCommissioning::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::AdministratorCommissioningCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = AdministratorCommissioning::Attributes::ClusterRevision::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

@end

@implementation MTRBaseClusterOperationalCredentials

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = endpoint;
    }
    return self;
}

- (void)attestationRequestWithParams:(MTROperationalCredentialsClusterAttestationRequestParams *)params
                   completionHandler:(void (^)(MTROperationalCredentialsClusterAttestationResponseParams * _Nullable data,
                                         NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTROperationalCredentialsClusterAttestationResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            OperationalCredentials::Commands::AttestationRequest::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.attestationNonce = [self asByteSpan:params.attestationNonce];

            auto successFn = Callback<OperationalCredentialsClusterAttestationResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OperationalCredentialsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)certificateChainRequestWithParams:(MTROperationalCredentialsClusterCertificateChainRequestParams *)params
                        completionHandler:(void (^)(MTROperationalCredentialsClusterCertificateChainResponseParams * _Nullable data,
                                              NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTROperationalCredentialsClusterCertificateChainResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            OperationalCredentials::Commands::CertificateChainRequest::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.certificateType = params.certificateType.unsignedCharValue;

            auto successFn = Callback<OperationalCredentialsClusterCertificateChainResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OperationalCredentialsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)CSRRequestWithParams:(MTROperationalCredentialsClusterCSRRequestParams *)params
           completionHandler:(void (^)(MTROperationalCredentialsClusterCSRResponseParams * _Nullable data,
                                 NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTROperationalCredentialsClusterCSRResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            OperationalCredentials::Commands::CSRRequest::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.CSRNonce = [self asByteSpan:params.csrNonce];
            if (params.isForUpdateNOC != nil) {
                auto & definedValue_0 = request.isForUpdateNOC.Emplace();
                definedValue_0 = params.isForUpdateNOC.boolValue;
            }

            auto successFn = Callback<OperationalCredentialsClusterCSRResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OperationalCredentialsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)addNOCWithParams:(MTROperationalCredentialsClusterAddNOCParams *)params
       completionHandler:(void (^)(MTROperationalCredentialsClusterNOCResponseParams * _Nullable data,
                             NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTROperationalCredentialsClusterNOCResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            OperationalCredentials::Commands::AddNOC::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.NOCValue = [self asByteSpan:params.nocValue];
            if (params.icacValue != nil) {
                auto & definedValue_0 = request.ICACValue.Emplace();
                definedValue_0 = [self asByteSpan:params.icacValue];
            }
            request.IPKValue = [self asByteSpan:params.ipkValue];
            request.caseAdminSubject = params.caseAdminSubject.unsignedLongLongValue;
            request.adminVendorId
                = static_cast<std::remove_reference_t<decltype(request.adminVendorId)>>(params.adminVendorId.unsignedShortValue);

            auto successFn = Callback<OperationalCredentialsClusterNOCResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OperationalCredentialsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)updateNOCWithParams:(MTROperationalCredentialsClusterUpdateNOCParams *)params
          completionHandler:(void (^)(MTROperationalCredentialsClusterNOCResponseParams * _Nullable data,
                                NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTROperationalCredentialsClusterNOCResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            OperationalCredentials::Commands::UpdateNOC::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.NOCValue = [self asByteSpan:params.nocValue];
            if (params.icacValue != nil) {
                auto & definedValue_0 = request.ICACValue.Emplace();
                definedValue_0 = [self asByteSpan:params.icacValue];
            }

            auto successFn = Callback<OperationalCredentialsClusterNOCResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OperationalCredentialsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)updateFabricLabelWithParams:(MTROperationalCredentialsClusterUpdateFabricLabelParams *)params
                  completionHandler:(void (^)(MTROperationalCredentialsClusterNOCResponseParams * _Nullable data,
                                        NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTROperationalCredentialsClusterNOCResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            OperationalCredentials::Commands::UpdateFabricLabel::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.label = [self asCharSpan:params.label];

            auto successFn = Callback<OperationalCredentialsClusterNOCResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OperationalCredentialsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)removeFabricWithParams:(MTROperationalCredentialsClusterRemoveFabricParams *)params
             completionHandler:(void (^)(MTROperationalCredentialsClusterNOCResponseParams * _Nullable data,
                                   NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTROperationalCredentialsClusterNOCResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            OperationalCredentials::Commands::RemoveFabric::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.fabricIndex = params.fabricIndex.unsignedCharValue;

            auto successFn = Callback<OperationalCredentialsClusterNOCResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OperationalCredentialsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)addTrustedRootCertificateWithParams:(MTROperationalCredentialsClusterAddTrustedRootCertificateParams *)params
                          completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            OperationalCredentials::Commands::AddTrustedRootCertificate::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.rootCertificate = [self asByteSpan:params.rootCertificate];

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OperationalCredentialsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)readAttributeNOCsWithParams:(MTRReadParams * _Nullable)params
                  completionHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{ // Make a copy of params before we go async.
    params = [params copy];
    new MTROperationalCredentialsNOCsListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = OperationalCredentials::Attributes::NOCs::TypeInfo;
            auto successFn = Callback<OperationalCredentialsNOCsListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OperationalCredentialsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue]);
        });
}

- (void)subscribeAttributeNOCsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                       params:(MTRSubscribeParams * _Nullable)params
                      subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTROperationalCredentialsNOCsListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = OperationalCredentials::Attributes::NOCs::TypeInfo;
            auto successFn = Callback<OperationalCredentialsNOCsListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::OperationalCredentialsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTROperationalCredentialsNOCsListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeNOCsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                   endpoint:(NSNumber *)endpoint
                                      queue:(dispatch_queue_t)queue
                          completionHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTROperationalCredentialsNOCsListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OperationalCredentials::Attributes::NOCs::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<OperationalCredentialsNOCsListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFabricsWithParams:(MTRReadParams * _Nullable)params
                     completionHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{ // Make a copy of params before we go async.
    params = [params copy];
    new MTROperationalCredentialsFabricsListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = OperationalCredentials::Attributes::Fabrics::TypeInfo;
            auto successFn = Callback<OperationalCredentialsFabricsListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OperationalCredentialsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue]);
        });
}

- (void)subscribeAttributeFabricsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                     maxInterval:(NSNumber * _Nonnull)maxInterval
                                          params:(MTRSubscribeParams * _Nullable)params
                         subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                   reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTROperationalCredentialsFabricsListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = OperationalCredentials::Attributes::Fabrics::TypeInfo;
            auto successFn = Callback<OperationalCredentialsFabricsListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::OperationalCredentialsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTROperationalCredentialsFabricsListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeFabricsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                      endpoint:(NSNumber *)endpoint
                                         queue:(dispatch_queue_t)queue
                             completionHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTROperationalCredentialsFabricsListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OperationalCredentials::Attributes::Fabrics::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<OperationalCredentialsFabricsListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeSupportedFabricsWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = OperationalCredentials::Attributes::SupportedFabrics::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OperationalCredentialsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeSupportedFabricsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                              maxInterval:(NSNumber * _Nonnull)maxInterval
                                                   params:(MTRSubscribeParams * _Nullable)params
                                  subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                            reportHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = OperationalCredentials::Attributes::SupportedFabrics::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::OperationalCredentialsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeSupportedFabricsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = OperationalCredentials::Attributes::SupportedFabrics::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeCommissionedFabricsWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = OperationalCredentials::Attributes::CommissionedFabrics::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OperationalCredentialsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeCommissionedFabricsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = OperationalCredentials::Attributes::CommissionedFabrics::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::OperationalCredentialsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeCommissionedFabricsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = OperationalCredentials::Attributes::CommissionedFabrics::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeTrustedRootCertificatesWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                      NSError * _Nullable error))completionHandler
{
    new MTROperationalCredentialsTrustedRootCertificatesListAttributeCallbackBridge(self.callbackQueue, self.device,
        completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = OperationalCredentials::Attributes::TrustedRootCertificates::TypeInfo;
            auto successFn = Callback<OperationalCredentialsTrustedRootCertificatesListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OperationalCredentialsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeTrustedRootCertificatesWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                     maxInterval:(NSNumber * _Nonnull)maxInterval
                                                          params:(MTRSubscribeParams * _Nullable)params
                                         subscriptionEstablished:
                                             (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                   reportHandler:
                                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTROperationalCredentialsTrustedRootCertificatesListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = OperationalCredentials::Attributes::TrustedRootCertificates::TypeInfo;
            auto successFn = Callback<OperationalCredentialsTrustedRootCertificatesListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::OperationalCredentialsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTROperationalCredentialsTrustedRootCertificatesListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished,
                nil, params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeTrustedRootCertificatesWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                             completionHandler:
                                                 (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTROperationalCredentialsTrustedRootCertificatesListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OperationalCredentials::Attributes::TrustedRootCertificates::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn
                    = Callback<OperationalCredentialsTrustedRootCertificatesListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeCurrentFabricIndexWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                 NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = OperationalCredentials::Attributes::CurrentFabricIndex::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OperationalCredentialsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeCurrentFabricIndexWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                maxInterval:(NSNumber * _Nonnull)maxInterval
                                                     params:(MTRSubscribeParams * _Nullable)params
                                    subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                              reportHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = OperationalCredentials::Attributes::CurrentFabricIndex::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::OperationalCredentialsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeCurrentFabricIndexWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                        completionHandler:
                                            (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = OperationalCredentials::Attributes::CurrentFabricIndex::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTROperationalCredentialsGeneratedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = OperationalCredentials::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<OperationalCredentialsGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OperationalCredentialsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTROperationalCredentialsGeneratedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = OperationalCredentials::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<OperationalCredentialsGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::OperationalCredentialsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTROperationalCredentialsGeneratedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished,
                nil, params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTROperationalCredentialsGeneratedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OperationalCredentials::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<OperationalCredentialsGeneratedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTROperationalCredentialsAcceptedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = OperationalCredentials::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<OperationalCredentialsAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OperationalCredentialsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTROperationalCredentialsAcceptedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = OperationalCredentials::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<OperationalCredentialsAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::OperationalCredentialsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTROperationalCredentialsAcceptedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTROperationalCredentialsAcceptedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OperationalCredentials::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<OperationalCredentialsAcceptedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTROperationalCredentialsAttributeListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = OperationalCredentials::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<OperationalCredentialsAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OperationalCredentialsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTROperationalCredentialsAttributeListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = OperationalCredentials::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<OperationalCredentialsAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::OperationalCredentialsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTROperationalCredentialsAttributeListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTROperationalCredentialsAttributeListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OperationalCredentials::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<OperationalCredentialsAttributeListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = OperationalCredentials::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OperationalCredentialsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = OperationalCredentials::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::OperationalCredentialsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = OperationalCredentials::Attributes::FeatureMap::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = OperationalCredentials::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OperationalCredentialsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = OperationalCredentials::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::OperationalCredentialsCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = OperationalCredentials::Attributes::ClusterRevision::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

@end

@implementation MTRBaseClusterGroupKeyManagement

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = endpoint;
    }
    return self;
}

- (void)keySetWriteWithParams:(MTRGroupKeyManagementClusterKeySetWriteParams *)params
            completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            GroupKeyManagement::Commands::KeySetWrite::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.groupKeySet.groupKeySetID = params.groupKeySet.groupKeySetID.unsignedShortValue;
            request.groupKeySet.groupKeySecurityPolicy
                = static_cast<std::remove_reference_t<decltype(request.groupKeySet.groupKeySecurityPolicy)>>(
                    params.groupKeySet.groupKeySecurityPolicy.unsignedCharValue);
            if (params.groupKeySet.epochKey0 == nil) {
                request.groupKeySet.epochKey0.SetNull();
            } else {
                auto & nonNullValue_1 = request.groupKeySet.epochKey0.SetNonNull();
                nonNullValue_1 = [self asByteSpan:params.groupKeySet.epochKey0];
            }
            if (params.groupKeySet.epochStartTime0 == nil) {
                request.groupKeySet.epochStartTime0.SetNull();
            } else {
                auto & nonNullValue_1 = request.groupKeySet.epochStartTime0.SetNonNull();
                nonNullValue_1 = params.groupKeySet.epochStartTime0.unsignedLongLongValue;
            }
            if (params.groupKeySet.epochKey1 == nil) {
                request.groupKeySet.epochKey1.SetNull();
            } else {
                auto & nonNullValue_1 = request.groupKeySet.epochKey1.SetNonNull();
                nonNullValue_1 = [self asByteSpan:params.groupKeySet.epochKey1];
            }
            if (params.groupKeySet.epochStartTime1 == nil) {
                request.groupKeySet.epochStartTime1.SetNull();
            } else {
                auto & nonNullValue_1 = request.groupKeySet.epochStartTime1.SetNonNull();
                nonNullValue_1 = params.groupKeySet.epochStartTime1.unsignedLongLongValue;
            }
            if (params.groupKeySet.epochKey2 == nil) {
                request.groupKeySet.epochKey2.SetNull();
            } else {
                auto & nonNullValue_1 = request.groupKeySet.epochKey2.SetNonNull();
                nonNullValue_1 = [self asByteSpan:params.groupKeySet.epochKey2];
            }
            if (params.groupKeySet.epochStartTime2 == nil) {
                request.groupKeySet.epochStartTime2.SetNull();
            } else {
                auto & nonNullValue_1 = request.groupKeySet.epochStartTime2.SetNonNull();
                nonNullValue_1 = params.groupKeySet.epochStartTime2.unsignedLongLongValue;
            }

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::GroupKeyManagementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)keySetReadWithParams:(MTRGroupKeyManagementClusterKeySetReadParams *)params
           completionHandler:(void (^)(MTRGroupKeyManagementClusterKeySetReadResponseParams * _Nullable data,
                                 NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRGroupKeyManagementClusterKeySetReadResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            GroupKeyManagement::Commands::KeySetRead::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.groupKeySetID = params.groupKeySetID.unsignedShortValue;

            auto successFn = Callback<GroupKeyManagementClusterKeySetReadResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::GroupKeyManagementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)keySetRemoveWithParams:(MTRGroupKeyManagementClusterKeySetRemoveParams *)params
             completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            GroupKeyManagement::Commands::KeySetRemove::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.groupKeySetID = params.groupKeySetID.unsignedShortValue;

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::GroupKeyManagementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)keySetReadAllIndicesWithParams:(MTRGroupKeyManagementClusterKeySetReadAllIndicesParams *)params
                     completionHandler:(void (^)(MTRGroupKeyManagementClusterKeySetReadAllIndicesResponseParams * _Nullable data,
                                           NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRGroupKeyManagementClusterKeySetReadAllIndicesResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            GroupKeyManagement::Commands::KeySetReadAllIndices::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            {
                using ListType_0 = std::remove_reference_t<decltype(request.groupKeySetIDs)>;
                using ListMemberType_0 = ListMemberTypeGetter<ListType_0>::Type;
                if (params.groupKeySetIDs.count != 0) {
                    auto * listHolder_0 = new ListHolder<ListMemberType_0>(params.groupKeySetIDs.count);
                    if (listHolder_0 == nullptr || listHolder_0->mList == nullptr) {
                        return CHIP_ERROR_INVALID_ARGUMENT;
                    }
                    listFreer.add(listHolder_0);
                    for (size_t i_0 = 0; i_0 < params.groupKeySetIDs.count; ++i_0) {
                        if (![params.groupKeySetIDs[i_0] isKindOfClass:[NSNumber class]]) {
                            // Wrong kind of value.
                            return CHIP_ERROR_INVALID_ARGUMENT;
                        }
                        auto element_0 = (NSNumber *) params.groupKeySetIDs[i_0];
                        listHolder_0->mList[i_0] = element_0.unsignedShortValue;
                    }
                    request.groupKeySetIDs = ListType_0(listHolder_0->mList, params.groupKeySetIDs.count);
                } else {
                    request.groupKeySetIDs = ListType_0();
                }
            }

            auto successFn = Callback<GroupKeyManagementClusterKeySetReadAllIndicesResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::GroupKeyManagementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)readAttributeGroupKeyMapWithParams:(MTRReadParams * _Nullable)params
                         completionHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{ // Make a copy of params before we go async.
    params = [params copy];
    new MTRGroupKeyManagementGroupKeyMapListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = GroupKeyManagement::Attributes::GroupKeyMap::TypeInfo;
            auto successFn = Callback<GroupKeyManagementGroupKeyMapListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::GroupKeyManagementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue]);
        });
}

- (void)writeAttributeGroupKeyMapWithValue:(NSArray * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeGroupKeyMapWithValue:(NSArray * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeGroupKeyMapWithValue:(NSArray * _Nonnull)value
                                    params:(MTRWriteParams * _Nullable)params
                         completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = GroupKeyManagement::Attributes::GroupKeyMap::TypeInfo;
            TypeInfo::Type cppValue;
            {
                using ListType_0 = std::remove_reference_t<decltype(cppValue)>;
                using ListMemberType_0 = ListMemberTypeGetter<ListType_0>::Type;
                if (value.count != 0) {
                    auto * listHolder_0 = new ListHolder<ListMemberType_0>(value.count);
                    if (listHolder_0 == nullptr || listHolder_0->mList == nullptr) {
                        return CHIP_ERROR_INVALID_ARGUMENT;
                    }
                    listFreer.add(listHolder_0);
                    for (size_t i_0 = 0; i_0 < value.count; ++i_0) {
                        if (![value[i_0] isKindOfClass:[MTRGroupKeyManagementClusterGroupKeyMapStruct class]]) {
                            // Wrong kind of value.
                            return CHIP_ERROR_INVALID_ARGUMENT;
                        }
                        auto element_0 = (MTRGroupKeyManagementClusterGroupKeyMapStruct *) value[i_0];
                        listHolder_0->mList[i_0].groupId = element_0.groupId.unsignedShortValue;
                        listHolder_0->mList[i_0].groupKeySetID = element_0.groupKeySetID.unsignedShortValue;
                        listHolder_0->mList[i_0].fabricIndex = element_0.fabricIndex.unsignedCharValue;
                    }
                    cppValue = ListType_0(listHolder_0->mList, value.count);
                } else {
                    cppValue = ListType_0();
                }
            }
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::GroupKeyManagementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeGroupKeyMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRGroupKeyManagementGroupKeyMapListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = GroupKeyManagement::Attributes::GroupKeyMap::TypeInfo;
            auto successFn = Callback<GroupKeyManagementGroupKeyMapListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::GroupKeyManagementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRGroupKeyManagementGroupKeyMapListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeGroupKeyMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRGroupKeyManagementGroupKeyMapListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = GroupKeyManagement::Attributes::GroupKeyMap::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<GroupKeyManagementGroupKeyMapListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGroupTableWithParams:(MTRReadParams * _Nullable)params
                        completionHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{ // Make a copy of params before we go async.
    params = [params copy];
    new MTRGroupKeyManagementGroupTableListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = GroupKeyManagement::Attributes::GroupTable::TypeInfo;
            auto successFn = Callback<GroupKeyManagementGroupTableListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::GroupKeyManagementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue]);
        });
}

- (void)subscribeAttributeGroupTableWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRGroupKeyManagementGroupTableListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = GroupKeyManagement::Attributes::GroupTable::TypeInfo;
            auto successFn = Callback<GroupKeyManagementGroupTableListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::GroupKeyManagementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRGroupKeyManagementGroupTableListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeGroupTableWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRGroupKeyManagementGroupTableListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = GroupKeyManagement::Attributes::GroupTable::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<GroupKeyManagementGroupTableListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeMaxGroupsPerFabricWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                 NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = GroupKeyManagement::Attributes::MaxGroupsPerFabric::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::GroupKeyManagementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeMaxGroupsPerFabricWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                maxInterval:(NSNumber * _Nonnull)maxInterval
                                                     params:(MTRSubscribeParams * _Nullable)params
                                    subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                              reportHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = GroupKeyManagement::Attributes::MaxGroupsPerFabric::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::GroupKeyManagementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeMaxGroupsPerFabricWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                        completionHandler:
                                            (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = GroupKeyManagement::Attributes::MaxGroupsPerFabric::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeMaxGroupKeysPerFabricWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                    NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = GroupKeyManagement::Attributes::MaxGroupKeysPerFabric::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::GroupKeyManagementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeMaxGroupKeysPerFabricWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                   maxInterval:(NSNumber * _Nonnull)maxInterval
                                                        params:(MTRSubscribeParams * _Nullable)params
                                       subscriptionEstablished:
                                           (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                 reportHandler:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = GroupKeyManagement::Attributes::MaxGroupKeysPerFabric::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::GroupKeyManagementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeMaxGroupKeysPerFabricWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                           completionHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = GroupKeyManagement::Attributes::MaxGroupKeysPerFabric::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRGroupKeyManagementGeneratedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = GroupKeyManagement::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<GroupKeyManagementGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::GroupKeyManagementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRGroupKeyManagementGeneratedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = GroupKeyManagement::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<GroupKeyManagementGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::GroupKeyManagementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRGroupKeyManagementGeneratedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRGroupKeyManagementGeneratedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = GroupKeyManagement::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<GroupKeyManagementGeneratedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRGroupKeyManagementAcceptedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = GroupKeyManagement::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<GroupKeyManagementAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::GroupKeyManagementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRGroupKeyManagementAcceptedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = GroupKeyManagement::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<GroupKeyManagementAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::GroupKeyManagementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRGroupKeyManagementAcceptedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRGroupKeyManagementAcceptedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = GroupKeyManagement::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<GroupKeyManagementAcceptedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRGroupKeyManagementAttributeListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = GroupKeyManagement::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<GroupKeyManagementAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::GroupKeyManagementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRGroupKeyManagementAttributeListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = GroupKeyManagement::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<GroupKeyManagementAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::GroupKeyManagementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRGroupKeyManagementAttributeListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRGroupKeyManagementAttributeListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = GroupKeyManagement::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<GroupKeyManagementAttributeListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = GroupKeyManagement::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::GroupKeyManagementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = GroupKeyManagement::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::GroupKeyManagementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = GroupKeyManagement::Attributes::FeatureMap::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = GroupKeyManagement::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::GroupKeyManagementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = GroupKeyManagement::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::GroupKeyManagementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = GroupKeyManagement::Attributes::ClusterRevision::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

@end

@implementation MTRBaseClusterFixedLabel

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = endpoint;
    }
    return self;
}

- (void)readAttributeLabelListWithCompletionHandler:(void (^)(
                                                        NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRFixedLabelLabelListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = FixedLabel::Attributes::LabelList::TypeInfo;
            auto successFn = Callback<FixedLabelLabelListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::FixedLabelCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeLabelListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRFixedLabelLabelListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = FixedLabel::Attributes::LabelList::TypeInfo;
            auto successFn = Callback<FixedLabelLabelListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::FixedLabelCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRFixedLabelLabelListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeLabelListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRFixedLabelLabelListListAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = FixedLabel::Attributes::LabelList::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<FixedLabelLabelListListAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRFixedLabelGeneratedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = FixedLabel::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<FixedLabelGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::FixedLabelCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRFixedLabelGeneratedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = FixedLabel::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<FixedLabelGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::FixedLabelCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRFixedLabelGeneratedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRFixedLabelGeneratedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = FixedLabel::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<FixedLabelGeneratedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRFixedLabelAcceptedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = FixedLabel::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<FixedLabelAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::FixedLabelCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRFixedLabelAcceptedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = FixedLabel::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<FixedLabelAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::FixedLabelCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRFixedLabelAcceptedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRFixedLabelAcceptedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = FixedLabel::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<FixedLabelAcceptedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRFixedLabelAttributeListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = FixedLabel::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<FixedLabelAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::FixedLabelCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRFixedLabelAttributeListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = FixedLabel::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<FixedLabelAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::FixedLabelCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRFixedLabelAttributeListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRFixedLabelAttributeListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = FixedLabel::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<FixedLabelAttributeListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = FixedLabel::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::FixedLabelCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = FixedLabel::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::FixedLabelCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = FixedLabel::Attributes::FeatureMap::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = FixedLabel::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::FixedLabelCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = FixedLabel::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::FixedLabelCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = FixedLabel::Attributes::ClusterRevision::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

@end

@implementation MTRBaseClusterUserLabel

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = endpoint;
    }
    return self;
}

- (void)readAttributeLabelListWithCompletionHandler:(void (^)(
                                                        NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRUserLabelLabelListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = UserLabel::Attributes::LabelList::TypeInfo;
            auto successFn = Callback<UserLabelLabelListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::UserLabelCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeLabelListWithValue:(NSArray * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeLabelListWithValue:(NSArray * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeLabelListWithValue:(NSArray * _Nonnull)value
                                  params:(MTRWriteParams * _Nullable)params
                       completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = UserLabel::Attributes::LabelList::TypeInfo;
            TypeInfo::Type cppValue;
            {
                using ListType_0 = std::remove_reference_t<decltype(cppValue)>;
                using ListMemberType_0 = ListMemberTypeGetter<ListType_0>::Type;
                if (value.count != 0) {
                    auto * listHolder_0 = new ListHolder<ListMemberType_0>(value.count);
                    if (listHolder_0 == nullptr || listHolder_0->mList == nullptr) {
                        return CHIP_ERROR_INVALID_ARGUMENT;
                    }
                    listFreer.add(listHolder_0);
                    for (size_t i_0 = 0; i_0 < value.count; ++i_0) {
                        if (![value[i_0] isKindOfClass:[MTRUserLabelClusterLabelStruct class]]) {
                            // Wrong kind of value.
                            return CHIP_ERROR_INVALID_ARGUMENT;
                        }
                        auto element_0 = (MTRUserLabelClusterLabelStruct *) value[i_0];
                        listHolder_0->mList[i_0].label = [self asCharSpan:element_0.label];
                        listHolder_0->mList[i_0].value = [self asCharSpan:element_0.value];
                    }
                    cppValue = ListType_0(listHolder_0->mList, value.count);
                } else {
                    cppValue = ListType_0();
                }
            }
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::UserLabelCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeLabelListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRUserLabelLabelListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = UserLabel::Attributes::LabelList::TypeInfo;
            auto successFn = Callback<UserLabelLabelListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::UserLabelCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRUserLabelLabelListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeLabelListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRUserLabelLabelListListAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = UserLabel::Attributes::LabelList::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<UserLabelLabelListListAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRUserLabelGeneratedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = UserLabel::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<UserLabelGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::UserLabelCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRUserLabelGeneratedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = UserLabel::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<UserLabelGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::UserLabelCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRUserLabelGeneratedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRUserLabelGeneratedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UserLabel::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<UserLabelGeneratedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRUserLabelAcceptedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = UserLabel::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<UserLabelAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::UserLabelCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRUserLabelAcceptedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = UserLabel::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<UserLabelAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::UserLabelCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRUserLabelAcceptedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRUserLabelAcceptedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UserLabel::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<UserLabelAcceptedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRUserLabelAttributeListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = UserLabel::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<UserLabelAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::UserLabelCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRUserLabelAttributeListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = UserLabel::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<UserLabelAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::UserLabelCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRUserLabelAttributeListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRUserLabelAttributeListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = UserLabel::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<UserLabelAttributeListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = UserLabel::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::UserLabelCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = UserLabel::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::UserLabelCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = UserLabel::Attributes::FeatureMap::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = UserLabel::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::UserLabelCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = UserLabel::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::UserLabelCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = UserLabel::Attributes::ClusterRevision::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

@end

@implementation MTRBaseClusterBooleanState

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = endpoint;
    }
    return self;
}

- (void)readAttributeStateValueWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBooleanAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BooleanState::Attributes::StateValue::TypeInfo;
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BooleanStateCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeStateValueWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRBooleanAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BooleanState::Attributes::StateValue::TypeInfo;
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BooleanStateCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRBooleanAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeStateValueWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBooleanAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = BooleanState::Attributes::StateValue::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRBooleanStateGeneratedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BooleanState::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<BooleanStateGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BooleanStateCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRBooleanStateGeneratedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BooleanState::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<BooleanStateGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BooleanStateCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRBooleanStateGeneratedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBooleanStateGeneratedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BooleanState::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<BooleanStateGeneratedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRBooleanStateAcceptedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BooleanState::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<BooleanStateAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BooleanStateCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRBooleanStateAcceptedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BooleanState::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<BooleanStateAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BooleanStateCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRBooleanStateAcceptedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBooleanStateAcceptedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BooleanState::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<BooleanStateAcceptedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBooleanStateAttributeListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BooleanState::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<BooleanStateAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BooleanStateCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRBooleanStateAttributeListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BooleanState::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<BooleanStateAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BooleanStateCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRBooleanStateAttributeListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBooleanStateAttributeListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BooleanState::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<BooleanStateAttributeListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BooleanState::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BooleanStateCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BooleanState::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BooleanStateCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = BooleanState::Attributes::FeatureMap::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BooleanState::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BooleanStateCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BooleanState::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BooleanStateCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = BooleanState::Attributes::ClusterRevision::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

@end

@implementation MTRBaseClusterModeSelect

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = endpoint;
    }
    return self;
}

- (void)changeToModeWithParams:(MTRModeSelectClusterChangeToModeParams *)params
             completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            ModeSelect::Commands::ChangeToMode::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.newMode = params.newMode.unsignedCharValue;

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ModeSelectCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)readAttributeDescriptionWithCompletionHandler:(void (^)(
                                                          NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ModeSelect::Attributes::Description::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ModeSelectCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeDescriptionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRCharStringAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ModeSelect::Attributes::Description::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ModeSelectCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRCharStringAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeDescriptionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ModeSelect::Attributes::Description::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeStandardNamespaceWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ModeSelect::Attributes::StandardNamespace::TypeInfo;
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ModeSelectCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeStandardNamespaceWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ModeSelect::Attributes::StandardNamespace::TypeInfo;
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ModeSelectCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeStandardNamespaceWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ModeSelect::Attributes::StandardNamespace::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeSupportedModesWithCompletionHandler:(void (^)(
                                                             NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRModeSelectSupportedModesListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ModeSelect::Attributes::SupportedModes::TypeInfo;
            auto successFn = Callback<ModeSelectSupportedModesListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ModeSelectCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeSupportedModesWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRModeSelectSupportedModesListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ModeSelect::Attributes::SupportedModes::TypeInfo;
            auto successFn = Callback<ModeSelectSupportedModesListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ModeSelectCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRModeSelectSupportedModesListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeSupportedModesWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRModeSelectSupportedModesListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ModeSelect::Attributes::SupportedModes::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<ModeSelectSupportedModesListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeCurrentModeWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ModeSelect::Attributes::CurrentMode::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ModeSelectCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeCurrentModeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ModeSelect::Attributes::CurrentMode::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ModeSelectCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeCurrentModeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ModeSelect::Attributes::CurrentMode::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeStartUpModeWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ModeSelect::Attributes::StartUpMode::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ModeSelectCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeStartUpModeWithValue:(NSNumber * _Nullable)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeStartUpModeWithValue:(NSNumber * _Nullable) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeStartUpModeWithValue:(NSNumber * _Nullable)value
                                    params:(MTRWriteParams * _Nullable)params
                         completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = ModeSelect::Attributes::StartUpMode::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.unsignedCharValue;
            }
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ModeSelectCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeStartUpModeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ModeSelect::Attributes::StartUpMode::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ModeSelectCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeStartUpModeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ModeSelect::Attributes::StartUpMode::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeOnModeWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ModeSelect::Attributes::OnMode::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ModeSelectCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeOnModeWithValue:(NSNumber * _Nullable)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeOnModeWithValue:(NSNumber * _Nullable) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeOnModeWithValue:(NSNumber * _Nullable)value
                               params:(MTRWriteParams * _Nullable)params
                    completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = ModeSelect::Attributes::OnMode::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.unsignedCharValue;
            }
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ModeSelectCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeOnModeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                         params:(MTRSubscribeParams * _Nullable)params
                        subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ModeSelect::Attributes::OnMode::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ModeSelectCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeOnModeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                     endpoint:(NSNumber *)endpoint
                                        queue:(dispatch_queue_t)queue
                            completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ModeSelect::Attributes::OnMode::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRModeSelectGeneratedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ModeSelect::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<ModeSelectGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ModeSelectCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRModeSelectGeneratedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ModeSelect::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<ModeSelectGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ModeSelectCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRModeSelectGeneratedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRModeSelectGeneratedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ModeSelect::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<ModeSelectGeneratedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRModeSelectAcceptedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ModeSelect::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<ModeSelectAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ModeSelectCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRModeSelectAcceptedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ModeSelect::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<ModeSelectAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ModeSelectCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRModeSelectAcceptedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRModeSelectAcceptedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ModeSelect::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<ModeSelectAcceptedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRModeSelectAttributeListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ModeSelect::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<ModeSelectAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ModeSelectCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRModeSelectAttributeListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ModeSelect::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<ModeSelectAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ModeSelectCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRModeSelectAttributeListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRModeSelectAttributeListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ModeSelect::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<ModeSelectAttributeListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ModeSelect::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ModeSelectCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ModeSelect::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ModeSelectCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ModeSelect::Attributes::FeatureMap::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ModeSelect::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ModeSelectCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ModeSelect::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ModeSelectCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ModeSelect::Attributes::ClusterRevision::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

@end

@implementation MTRBaseClusterDoorLock

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = endpoint;
    }
    return self;
}

- (void)lockDoorWithParams:(MTRDoorLockClusterLockDoorParams * _Nullable)params
         completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            DoorLock::Commands::LockDoor::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            if (!timedInvokeTimeoutMs.HasValue()) {
                timedInvokeTimeoutMs.SetValue(10000);
            }
            if (params != nil) {
                if (params.pinCode != nil) {
                    auto & definedValue_0 = request.pinCode.Emplace();
                    definedValue_0 = [self asByteSpan:params.pinCode];
                }
            }

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)unlockDoorWithParams:(MTRDoorLockClusterUnlockDoorParams * _Nullable)params
           completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            DoorLock::Commands::UnlockDoor::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            if (!timedInvokeTimeoutMs.HasValue()) {
                timedInvokeTimeoutMs.SetValue(10000);
            }
            if (params != nil) {
                if (params.pinCode != nil) {
                    auto & definedValue_0 = request.pinCode.Emplace();
                    definedValue_0 = [self asByteSpan:params.pinCode];
                }
            }

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)unlockWithTimeoutWithParams:(MTRDoorLockClusterUnlockWithTimeoutParams *)params
                  completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            DoorLock::Commands::UnlockWithTimeout::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            if (!timedInvokeTimeoutMs.HasValue()) {
                timedInvokeTimeoutMs.SetValue(10000);
            }
            request.timeout = params.timeout.unsignedShortValue;
            if (params.pinCode != nil) {
                auto & definedValue_0 = request.pinCode.Emplace();
                definedValue_0 = [self asByteSpan:params.pinCode];
            }

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)setWeekDayScheduleWithParams:(MTRDoorLockClusterSetWeekDayScheduleParams *)params
                   completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            DoorLock::Commands::SetWeekDaySchedule::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.weekDayIndex = params.weekDayIndex.unsignedCharValue;
            request.userIndex = params.userIndex.unsignedShortValue;
            request.daysMask = static_cast<std::remove_reference_t<decltype(request.daysMask)>>(params.daysMask.unsignedCharValue);
            request.startHour = params.startHour.unsignedCharValue;
            request.startMinute = params.startMinute.unsignedCharValue;
            request.endHour = params.endHour.unsignedCharValue;
            request.endMinute = params.endMinute.unsignedCharValue;

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)getWeekDayScheduleWithParams:(MTRDoorLockClusterGetWeekDayScheduleParams *)params
                   completionHandler:(void (^)(MTRDoorLockClusterGetWeekDayScheduleResponseParams * _Nullable data,
                                         NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRDoorLockClusterGetWeekDayScheduleResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            DoorLock::Commands::GetWeekDaySchedule::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.weekDayIndex = params.weekDayIndex.unsignedCharValue;
            request.userIndex = params.userIndex.unsignedShortValue;

            auto successFn = Callback<DoorLockClusterGetWeekDayScheduleResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)clearWeekDayScheduleWithParams:(MTRDoorLockClusterClearWeekDayScheduleParams *)params
                     completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            DoorLock::Commands::ClearWeekDaySchedule::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.weekDayIndex = params.weekDayIndex.unsignedCharValue;
            request.userIndex = params.userIndex.unsignedShortValue;

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)setYearDayScheduleWithParams:(MTRDoorLockClusterSetYearDayScheduleParams *)params
                   completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            DoorLock::Commands::SetYearDaySchedule::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.yearDayIndex = params.yearDayIndex.unsignedCharValue;
            request.userIndex = params.userIndex.unsignedShortValue;
            request.localStartTime = params.localStartTime.unsignedIntValue;
            request.localEndTime = params.localEndTime.unsignedIntValue;

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)getYearDayScheduleWithParams:(MTRDoorLockClusterGetYearDayScheduleParams *)params
                   completionHandler:(void (^)(MTRDoorLockClusterGetYearDayScheduleResponseParams * _Nullable data,
                                         NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRDoorLockClusterGetYearDayScheduleResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            DoorLock::Commands::GetYearDaySchedule::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.yearDayIndex = params.yearDayIndex.unsignedCharValue;
            request.userIndex = params.userIndex.unsignedShortValue;

            auto successFn = Callback<DoorLockClusterGetYearDayScheduleResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)clearYearDayScheduleWithParams:(MTRDoorLockClusterClearYearDayScheduleParams *)params
                     completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            DoorLock::Commands::ClearYearDaySchedule::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.yearDayIndex = params.yearDayIndex.unsignedCharValue;
            request.userIndex = params.userIndex.unsignedShortValue;

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)setHolidayScheduleWithParams:(MTRDoorLockClusterSetHolidayScheduleParams *)params
                   completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            DoorLock::Commands::SetHolidaySchedule::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.holidayIndex = params.holidayIndex.unsignedCharValue;
            request.localStartTime = params.localStartTime.unsignedIntValue;
            request.localEndTime = params.localEndTime.unsignedIntValue;
            request.operatingMode
                = static_cast<std::remove_reference_t<decltype(request.operatingMode)>>(params.operatingMode.unsignedCharValue);

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)getHolidayScheduleWithParams:(MTRDoorLockClusterGetHolidayScheduleParams *)params
                   completionHandler:(void (^)(MTRDoorLockClusterGetHolidayScheduleResponseParams * _Nullable data,
                                         NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRDoorLockClusterGetHolidayScheduleResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            DoorLock::Commands::GetHolidaySchedule::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.holidayIndex = params.holidayIndex.unsignedCharValue;

            auto successFn = Callback<DoorLockClusterGetHolidayScheduleResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)clearHolidayScheduleWithParams:(MTRDoorLockClusterClearHolidayScheduleParams *)params
                     completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            DoorLock::Commands::ClearHolidaySchedule::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.holidayIndex = params.holidayIndex.unsignedCharValue;

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)setUserWithParams:(MTRDoorLockClusterSetUserParams *)params completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            DoorLock::Commands::SetUser::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            if (!timedInvokeTimeoutMs.HasValue()) {
                timedInvokeTimeoutMs.SetValue(10000);
            }
            request.operationType
                = static_cast<std::remove_reference_t<decltype(request.operationType)>>(params.operationType.unsignedCharValue);
            request.userIndex = params.userIndex.unsignedShortValue;
            if (params.userName == nil) {
                request.userName.SetNull();
            } else {
                auto & nonNullValue_0 = request.userName.SetNonNull();
                nonNullValue_0 = [self asCharSpan:params.userName];
            }
            if (params.userUniqueId == nil) {
                request.userUniqueId.SetNull();
            } else {
                auto & nonNullValue_0 = request.userUniqueId.SetNonNull();
                nonNullValue_0 = params.userUniqueId.unsignedIntValue;
            }
            if (params.userStatus == nil) {
                request.userStatus.SetNull();
            } else {
                auto & nonNullValue_0 = request.userStatus.SetNonNull();
                nonNullValue_0
                    = static_cast<std::remove_reference_t<decltype(nonNullValue_0)>>(params.userStatus.unsignedCharValue);
            }
            if (params.userType == nil) {
                request.userType.SetNull();
            } else {
                auto & nonNullValue_0 = request.userType.SetNonNull();
                nonNullValue_0 = static_cast<std::remove_reference_t<decltype(nonNullValue_0)>>(params.userType.unsignedCharValue);
            }
            if (params.credentialRule == nil) {
                request.credentialRule.SetNull();
            } else {
                auto & nonNullValue_0 = request.credentialRule.SetNonNull();
                nonNullValue_0
                    = static_cast<std::remove_reference_t<decltype(nonNullValue_0)>>(params.credentialRule.unsignedCharValue);
            }

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)getUserWithParams:(MTRDoorLockClusterGetUserParams *)params
        completionHandler:
            (void (^)(MTRDoorLockClusterGetUserResponseParams * _Nullable data, NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRDoorLockClusterGetUserResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            DoorLock::Commands::GetUser::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.userIndex = params.userIndex.unsignedShortValue;

            auto successFn = Callback<DoorLockClusterGetUserResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)clearUserWithParams:(MTRDoorLockClusterClearUserParams *)params completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            DoorLock::Commands::ClearUser::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            if (!timedInvokeTimeoutMs.HasValue()) {
                timedInvokeTimeoutMs.SetValue(10000);
            }
            request.userIndex = params.userIndex.unsignedShortValue;

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)setCredentialWithParams:(MTRDoorLockClusterSetCredentialParams *)params
              completionHandler:(void (^)(MTRDoorLockClusterSetCredentialResponseParams * _Nullable data,
                                    NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRDoorLockClusterSetCredentialResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            DoorLock::Commands::SetCredential::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            if (!timedInvokeTimeoutMs.HasValue()) {
                timedInvokeTimeoutMs.SetValue(10000);
            }
            request.operationType
                = static_cast<std::remove_reference_t<decltype(request.operationType)>>(params.operationType.unsignedCharValue);
            request.credential.credentialType = static_cast<std::remove_reference_t<decltype(request.credential.credentialType)>>(
                params.credential.credentialType.unsignedCharValue);
            request.credential.credentialIndex = params.credential.credentialIndex.unsignedShortValue;
            request.credentialData = [self asByteSpan:params.credentialData];
            if (params.userIndex == nil) {
                request.userIndex.SetNull();
            } else {
                auto & nonNullValue_0 = request.userIndex.SetNonNull();
                nonNullValue_0 = params.userIndex.unsignedShortValue;
            }
            if (params.userStatus == nil) {
                request.userStatus.SetNull();
            } else {
                auto & nonNullValue_0 = request.userStatus.SetNonNull();
                nonNullValue_0
                    = static_cast<std::remove_reference_t<decltype(nonNullValue_0)>>(params.userStatus.unsignedCharValue);
            }
            if (params.userType == nil) {
                request.userType.SetNull();
            } else {
                auto & nonNullValue_0 = request.userType.SetNonNull();
                nonNullValue_0 = static_cast<std::remove_reference_t<decltype(nonNullValue_0)>>(params.userType.unsignedCharValue);
            }

            auto successFn = Callback<DoorLockClusterSetCredentialResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)getCredentialStatusWithParams:(MTRDoorLockClusterGetCredentialStatusParams *)params
                    completionHandler:(void (^)(MTRDoorLockClusterGetCredentialStatusResponseParams * _Nullable data,
                                          NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRDoorLockClusterGetCredentialStatusResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            DoorLock::Commands::GetCredentialStatus::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.credential.credentialType = static_cast<std::remove_reference_t<decltype(request.credential.credentialType)>>(
                params.credential.credentialType.unsignedCharValue);
            request.credential.credentialIndex = params.credential.credentialIndex.unsignedShortValue;

            auto successFn = Callback<DoorLockClusterGetCredentialStatusResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)clearCredentialWithParams:(MTRDoorLockClusterClearCredentialParams *)params
                completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            DoorLock::Commands::ClearCredential::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            if (!timedInvokeTimeoutMs.HasValue()) {
                timedInvokeTimeoutMs.SetValue(10000);
            }
            if (params.credential == nil) {
                request.credential.SetNull();
            } else {
                auto & nonNullValue_0 = request.credential.SetNonNull();
                nonNullValue_0.credentialType = static_cast<std::remove_reference_t<decltype(nonNullValue_0.credentialType)>>(
                    params.credential.credentialType.unsignedCharValue);
                nonNullValue_0.credentialIndex = params.credential.credentialIndex.unsignedShortValue;
            }

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)readAttributeLockStateWithCompletionHandler:(void (^)(
                                                        NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableDoorLockClusterDlLockStateAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = DoorLock::Attributes::LockState::TypeInfo;
            auto successFn = Callback<NullableDoorLockClusterDlLockStateAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeLockStateWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableDoorLockClusterDlLockStateAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = DoorLock::Attributes::LockState::TypeInfo;
            auto successFn = Callback<NullableDoorLockClusterDlLockStateAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableDoorLockClusterDlLockStateAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeLockStateWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableDoorLockClusterDlLockStateAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = DoorLock::Attributes::LockState::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<NullableDoorLockClusterDlLockStateAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeLockTypeWithCompletionHandler:(void (^)(
                                                       NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRDoorLockClusterDlLockTypeAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = DoorLock::Attributes::LockType::TypeInfo;
            auto successFn = Callback<DoorLockClusterDlLockTypeAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeLockTypeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                           params:(MTRSubscribeParams * _Nullable)params
                          subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRDoorLockClusterDlLockTypeAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = DoorLock::Attributes::LockType::TypeInfo;
            auto successFn = Callback<DoorLockClusterDlLockTypeAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRDoorLockClusterDlLockTypeAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeLockTypeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                       endpoint:(NSNumber *)endpoint
                                          queue:(dispatch_queue_t)queue
                              completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRDoorLockClusterDlLockTypeAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = DoorLock::Attributes::LockType::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<DoorLockClusterDlLockTypeAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeActuatorEnabledWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRBooleanAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = DoorLock::Attributes::ActuatorEnabled::TypeInfo;
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeActuatorEnabledWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRBooleanAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = DoorLock::Attributes::ActuatorEnabled::TypeInfo;
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRBooleanAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeActuatorEnabledWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBooleanAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = DoorLock::Attributes::ActuatorEnabled::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeDoorStateWithCompletionHandler:(void (^)(
                                                        NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableDoorLockClusterDlDoorStateAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = DoorLock::Attributes::DoorState::TypeInfo;
            auto successFn = Callback<NullableDoorLockClusterDlDoorStateAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeDoorStateWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableDoorLockClusterDlDoorStateAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = DoorLock::Attributes::DoorState::TypeInfo;
            auto successFn = Callback<NullableDoorLockClusterDlDoorStateAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableDoorLockClusterDlDoorStateAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeDoorStateWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableDoorLockClusterDlDoorStateAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = DoorLock::Attributes::DoorState::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<NullableDoorLockClusterDlDoorStateAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeDoorOpenEventsWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = DoorLock::Attributes::DoorOpenEvents::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeDoorOpenEventsWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeDoorOpenEventsWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeDoorOpenEventsWithValue:(NSNumber * _Nonnull)value
                                       params:(MTRWriteParams * _Nullable)params
                            completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = DoorLock::Attributes::DoorOpenEvents::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedIntValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeDoorOpenEventsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = DoorLock::Attributes::DoorOpenEvents::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeDoorOpenEventsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = DoorLock::Attributes::DoorOpenEvents::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeDoorClosedEventsWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = DoorLock::Attributes::DoorClosedEvents::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeDoorClosedEventsWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeDoorClosedEventsWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeDoorClosedEventsWithValue:(NSNumber * _Nonnull)value
                                         params:(MTRWriteParams * _Nullable)params
                              completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = DoorLock::Attributes::DoorClosedEvents::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedIntValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeDoorClosedEventsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                              maxInterval:(NSNumber * _Nonnull)maxInterval
                                                   params:(MTRSubscribeParams * _Nullable)params
                                  subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                            reportHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = DoorLock::Attributes::DoorClosedEvents::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeDoorClosedEventsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = DoorLock::Attributes::DoorClosedEvents::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeOpenPeriodWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = DoorLock::Attributes::OpenPeriod::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeOpenPeriodWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeOpenPeriodWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeOpenPeriodWithValue:(NSNumber * _Nonnull)value
                                   params:(MTRWriteParams * _Nullable)params
                        completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = DoorLock::Attributes::OpenPeriod::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeOpenPeriodWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = DoorLock::Attributes::OpenPeriod::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeOpenPeriodWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = DoorLock::Attributes::OpenPeriod::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeNumberOfTotalUsersSupportedWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                          NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = DoorLock::Attributes::NumberOfTotalUsersSupported::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeNumberOfTotalUsersSupportedWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                                              params:(MTRSubscribeParams * _Nullable)params
                                             subscriptionEstablished:
                                                 (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                       reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = DoorLock::Attributes::NumberOfTotalUsersSupported::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeNumberOfTotalUsersSupportedWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                          endpoint:(NSNumber *)endpoint
                                                             queue:(dispatch_queue_t)queue
                                                 completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = DoorLock::Attributes::NumberOfTotalUsersSupported::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeNumberOfPINUsersSupportedWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = DoorLock::Attributes::NumberOfPINUsersSupported::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeNumberOfPINUsersSupportedWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                                            params:(MTRSubscribeParams * _Nullable)params
                                           subscriptionEstablished:
                                               (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                     reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = DoorLock::Attributes::NumberOfPINUsersSupported::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeNumberOfPINUsersSupportedWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                        endpoint:(NSNumber *)endpoint
                                                           queue:(dispatch_queue_t)queue
                                               completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = DoorLock::Attributes::NumberOfPINUsersSupported::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeNumberOfRFIDUsersSupportedWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = DoorLock::Attributes::NumberOfRFIDUsersSupported::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeNumberOfRFIDUsersSupportedWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                                             params:(MTRSubscribeParams * _Nullable)params
                                            subscriptionEstablished:
                                                (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                      reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = DoorLock::Attributes::NumberOfRFIDUsersSupported::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeNumberOfRFIDUsersSupportedWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                         endpoint:(NSNumber *)endpoint
                                                            queue:(dispatch_queue_t)queue
                                                completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = DoorLock::Attributes::NumberOfRFIDUsersSupported::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeNumberOfWeekDaySchedulesSupportedPerUserWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                                       NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = DoorLock::Attributes::NumberOfWeekDaySchedulesSupportedPerUser::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeNumberOfWeekDaySchedulesSupportedPerUserWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                           params:(MTRSubscribeParams * _Nullable)params
                                                          subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)
                                                                                      subscriptionEstablishedHandler
                                                                    reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                                      NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = DoorLock::Attributes::NumberOfWeekDaySchedulesSupportedPerUser::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeNumberOfWeekDaySchedulesSupportedPerUserWithAttributeCache:
            (MTRAttributeCacheContainer *)attributeCacheContainer
                                                                       endpoint:(NSNumber *)endpoint
                                                                          queue:(dispatch_queue_t)queue
                                                              completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                                    NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = DoorLock::Attributes::NumberOfWeekDaySchedulesSupportedPerUser::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeNumberOfYearDaySchedulesSupportedPerUserWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                                       NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = DoorLock::Attributes::NumberOfYearDaySchedulesSupportedPerUser::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeNumberOfYearDaySchedulesSupportedPerUserWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                           params:(MTRSubscribeParams * _Nullable)params
                                                          subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)
                                                                                      subscriptionEstablishedHandler
                                                                    reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                                      NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = DoorLock::Attributes::NumberOfYearDaySchedulesSupportedPerUser::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeNumberOfYearDaySchedulesSupportedPerUserWithAttributeCache:
            (MTRAttributeCacheContainer *)attributeCacheContainer
                                                                       endpoint:(NSNumber *)endpoint
                                                                          queue:(dispatch_queue_t)queue
                                                              completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                                    NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = DoorLock::Attributes::NumberOfYearDaySchedulesSupportedPerUser::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeNumberOfHolidaySchedulesSupportedWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                                NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = DoorLock::Attributes::NumberOfHolidaySchedulesSupported::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeNumberOfHolidaySchedulesSupportedWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                    params:(MTRSubscribeParams * _Nullable)params
                                                   subscriptionEstablished:
                                                       (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                             reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                               NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = DoorLock::Attributes::NumberOfHolidaySchedulesSupported::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeNumberOfHolidaySchedulesSupportedWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                                endpoint:(NSNumber *)endpoint
                                                                   queue:(dispatch_queue_t)queue
                                                       completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                             NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = DoorLock::Attributes::NumberOfHolidaySchedulesSupported::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeMaxPINCodeLengthWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = DoorLock::Attributes::MaxPINCodeLength::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeMaxPINCodeLengthWithMinInterval:(NSNumber * _Nonnull)minInterval
                                              maxInterval:(NSNumber * _Nonnull)maxInterval
                                                   params:(MTRSubscribeParams * _Nullable)params
                                  subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                            reportHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = DoorLock::Attributes::MaxPINCodeLength::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeMaxPINCodeLengthWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = DoorLock::Attributes::MaxPINCodeLength::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeMinPINCodeLengthWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = DoorLock::Attributes::MinPINCodeLength::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeMinPINCodeLengthWithMinInterval:(NSNumber * _Nonnull)minInterval
                                              maxInterval:(NSNumber * _Nonnull)maxInterval
                                                   params:(MTRSubscribeParams * _Nullable)params
                                  subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                            reportHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = DoorLock::Attributes::MinPINCodeLength::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeMinPINCodeLengthWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = DoorLock::Attributes::MinPINCodeLength::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeMaxRFIDCodeLengthWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = DoorLock::Attributes::MaxRFIDCodeLength::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeMaxRFIDCodeLengthWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = DoorLock::Attributes::MaxRFIDCodeLength::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeMaxRFIDCodeLengthWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = DoorLock::Attributes::MaxRFIDCodeLength::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeMinRFIDCodeLengthWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = DoorLock::Attributes::MinRFIDCodeLength::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeMinRFIDCodeLengthWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = DoorLock::Attributes::MinRFIDCodeLength::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeMinRFIDCodeLengthWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = DoorLock::Attributes::MinRFIDCodeLength::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeCredentialRulesSupportWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completionHandler
{
    new MTRDoorLockCredentialRulesSupportAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = DoorLock::Attributes::CredentialRulesSupport::TypeInfo;
            auto successFn = Callback<DoorLockCredentialRulesSupportAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeCredentialRulesSupportWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                                         params:(MTRSubscribeParams * _Nullable)params
                                        subscriptionEstablished:
                                            (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                  reportHandler:
                                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRDoorLockCredentialRulesSupportAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = DoorLock::Attributes::CredentialRulesSupport::TypeInfo;
            auto successFn = Callback<DoorLockCredentialRulesSupportAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRDoorLockCredentialRulesSupportAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeCredentialRulesSupportWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                            completionHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRDoorLockCredentialRulesSupportAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = DoorLock::Attributes::CredentialRulesSupport::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<DoorLockCredentialRulesSupportAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeNumberOfCredentialsSupportedPerUserWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                                  NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = DoorLock::Attributes::NumberOfCredentialsSupportedPerUser::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeNumberOfCredentialsSupportedPerUserWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                      params:(MTRSubscribeParams * _Nullable)params
                                                     subscriptionEstablished:
                                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                               reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                                 NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = DoorLock::Attributes::NumberOfCredentialsSupportedPerUser::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeNumberOfCredentialsSupportedPerUserWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                                  endpoint:(NSNumber *)endpoint
                                                                     queue:(dispatch_queue_t)queue
                                                         completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                               NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = DoorLock::Attributes::NumberOfCredentialsSupportedPerUser::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeLanguageWithCompletionHandler:(void (^)(
                                                       NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = DoorLock::Attributes::Language::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeLanguageWithValue:(NSString * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeLanguageWithValue:(NSString * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeLanguageWithValue:(NSString * _Nonnull)value
                                 params:(MTRWriteParams * _Nullable)params
                      completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = DoorLock::Attributes::Language::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = [self asCharSpan:value];
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeLanguageWithMinInterval:(NSNumber * _Nonnull)minInterval
                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                           params:(MTRSubscribeParams * _Nullable)params
                          subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                    reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRCharStringAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = DoorLock::Attributes::Language::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRCharStringAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeLanguageWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                       endpoint:(NSNumber *)endpoint
                                          queue:(dispatch_queue_t)queue
                              completionHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = DoorLock::Attributes::Language::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeLEDSettingsWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = DoorLock::Attributes::LEDSettings::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeLEDSettingsWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeLEDSettingsWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeLEDSettingsWithValue:(NSNumber * _Nonnull)value
                                    params:(MTRWriteParams * _Nullable)params
                         completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = DoorLock::Attributes::LEDSettings::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedCharValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeLEDSettingsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = DoorLock::Attributes::LEDSettings::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeLEDSettingsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = DoorLock::Attributes::LEDSettings::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeAutoRelockTimeWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = DoorLock::Attributes::AutoRelockTime::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeAutoRelockTimeWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeAutoRelockTimeWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeAutoRelockTimeWithValue:(NSNumber * _Nonnull)value
                                       params:(MTRWriteParams * _Nullable)params
                            completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = DoorLock::Attributes::AutoRelockTime::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedIntValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeAutoRelockTimeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = DoorLock::Attributes::AutoRelockTime::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAutoRelockTimeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = DoorLock::Attributes::AutoRelockTime::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeSoundVolumeWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = DoorLock::Attributes::SoundVolume::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeSoundVolumeWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeSoundVolumeWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeSoundVolumeWithValue:(NSNumber * _Nonnull)value
                                    params:(MTRWriteParams * _Nullable)params
                         completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = DoorLock::Attributes::SoundVolume::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedCharValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeSoundVolumeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = DoorLock::Attributes::SoundVolume::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeSoundVolumeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = DoorLock::Attributes::SoundVolume::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeOperatingModeWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRDoorLockClusterDlOperatingModeAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = DoorLock::Attributes::OperatingMode::TypeInfo;
            auto successFn = Callback<DoorLockClusterDlOperatingModeAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeOperatingModeWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeOperatingModeWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeOperatingModeWithValue:(NSNumber * _Nonnull)value
                                      params:(MTRWriteParams * _Nullable)params
                           completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = DoorLock::Attributes::OperatingMode::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = static_cast<std::remove_reference_t<decltype(cppValue)>>(value.unsignedCharValue);
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeOperatingModeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRDoorLockClusterDlOperatingModeAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = DoorLock::Attributes::OperatingMode::TypeInfo;
            auto successFn = Callback<DoorLockClusterDlOperatingModeAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRDoorLockClusterDlOperatingModeAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeOperatingModeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRDoorLockClusterDlOperatingModeAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = DoorLock::Attributes::OperatingMode::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<DoorLockClusterDlOperatingModeAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeSupportedOperatingModesWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))completionHandler
{
    new MTRDoorLockSupportedOperatingModesAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = DoorLock::Attributes::SupportedOperatingModes::TypeInfo;
            auto successFn = Callback<DoorLockSupportedOperatingModesAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeSupportedOperatingModesWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                     maxInterval:(NSNumber * _Nonnull)maxInterval
                                                          params:(MTRSubscribeParams * _Nullable)params
                                         subscriptionEstablished:
                                             (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                   reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRDoorLockSupportedOperatingModesAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = DoorLock::Attributes::SupportedOperatingModes::TypeInfo;
            auto successFn = Callback<DoorLockSupportedOperatingModesAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRDoorLockSupportedOperatingModesAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeSupportedOperatingModesWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                             completionHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRDoorLockSupportedOperatingModesAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = DoorLock::Attributes::SupportedOperatingModes::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<DoorLockSupportedOperatingModesAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeDefaultConfigurationRegisterWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))completionHandler
{
    new MTRDoorLockDefaultConfigurationRegisterAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = DoorLock::Attributes::DefaultConfigurationRegister::TypeInfo;
            auto successFn = Callback<DoorLockDefaultConfigurationRegisterAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeDefaultConfigurationRegisterWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                                               params:(MTRSubscribeParams * _Nullable)params
                                              subscriptionEstablished:
                                                  (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                        reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                          NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRDoorLockDefaultConfigurationRegisterAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = DoorLock::Attributes::DefaultConfigurationRegister::TypeInfo;
            auto successFn = Callback<DoorLockDefaultConfigurationRegisterAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRDoorLockDefaultConfigurationRegisterAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeDefaultConfigurationRegisterWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                           endpoint:(NSNumber *)endpoint
                                                              queue:(dispatch_queue_t)queue
                                                  completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))completionHandler
{
    new MTRDoorLockDefaultConfigurationRegisterAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = DoorLock::Attributes::DefaultConfigurationRegister::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<DoorLockDefaultConfigurationRegisterAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEnableLocalProgrammingWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completionHandler
{
    new MTRBooleanAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = DoorLock::Attributes::EnableLocalProgramming::TypeInfo;
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeEnableLocalProgrammingWithValue:(NSNumber * _Nonnull)value
                                    completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeEnableLocalProgrammingWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeEnableLocalProgrammingWithValue:(NSNumber * _Nonnull)value
                                               params:(MTRWriteParams * _Nullable)params
                                    completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = DoorLock::Attributes::EnableLocalProgramming::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.boolValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeEnableLocalProgrammingWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                                         params:(MTRSubscribeParams * _Nullable)params
                                        subscriptionEstablished:
                                            (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                  reportHandler:
                                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRBooleanAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = DoorLock::Attributes::EnableLocalProgramming::TypeInfo;
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRBooleanAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeEnableLocalProgrammingWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                            completionHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBooleanAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = DoorLock::Attributes::EnableLocalProgramming::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeEnableOneTouchLockingWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                    NSError * _Nullable error))completionHandler
{
    new MTRBooleanAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = DoorLock::Attributes::EnableOneTouchLocking::TypeInfo;
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeEnableOneTouchLockingWithValue:(NSNumber * _Nonnull)value
                                   completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeEnableOneTouchLockingWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeEnableOneTouchLockingWithValue:(NSNumber * _Nonnull)value
                                              params:(MTRWriteParams * _Nullable)params
                                   completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = DoorLock::Attributes::EnableOneTouchLocking::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.boolValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeEnableOneTouchLockingWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                   maxInterval:(NSNumber * _Nonnull)maxInterval
                                                        params:(MTRSubscribeParams * _Nullable)params
                                       subscriptionEstablished:
                                           (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                 reportHandler:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRBooleanAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = DoorLock::Attributes::EnableOneTouchLocking::TypeInfo;
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRBooleanAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeEnableOneTouchLockingWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                           completionHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBooleanAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = DoorLock::Attributes::EnableOneTouchLocking::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeEnableInsideStatusLEDWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                    NSError * _Nullable error))completionHandler
{
    new MTRBooleanAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = DoorLock::Attributes::EnableInsideStatusLED::TypeInfo;
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeEnableInsideStatusLEDWithValue:(NSNumber * _Nonnull)value
                                   completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeEnableInsideStatusLEDWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeEnableInsideStatusLEDWithValue:(NSNumber * _Nonnull)value
                                              params:(MTRWriteParams * _Nullable)params
                                   completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = DoorLock::Attributes::EnableInsideStatusLED::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.boolValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeEnableInsideStatusLEDWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                   maxInterval:(NSNumber * _Nonnull)maxInterval
                                                        params:(MTRSubscribeParams * _Nullable)params
                                       subscriptionEstablished:
                                           (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                 reportHandler:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRBooleanAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = DoorLock::Attributes::EnableInsideStatusLED::TypeInfo;
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRBooleanAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeEnableInsideStatusLEDWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                           completionHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBooleanAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = DoorLock::Attributes::EnableInsideStatusLED::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeEnablePrivacyModeButtonWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))completionHandler
{
    new MTRBooleanAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = DoorLock::Attributes::EnablePrivacyModeButton::TypeInfo;
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeEnablePrivacyModeButtonWithValue:(NSNumber * _Nonnull)value
                                     completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeEnablePrivacyModeButtonWithValue:(NSNumber * _Nonnull) value
                                                  params:nil
                                       completionHandler:completionHandler];
}
- (void)writeAttributeEnablePrivacyModeButtonWithValue:(NSNumber * _Nonnull)value
                                                params:(MTRWriteParams * _Nullable)params
                                     completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = DoorLock::Attributes::EnablePrivacyModeButton::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.boolValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeEnablePrivacyModeButtonWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                     maxInterval:(NSNumber * _Nonnull)maxInterval
                                                          params:(MTRSubscribeParams * _Nullable)params
                                         subscriptionEstablished:
                                             (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                   reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRBooleanAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = DoorLock::Attributes::EnablePrivacyModeButton::TypeInfo;
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRBooleanAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeEnablePrivacyModeButtonWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                             completionHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBooleanAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = DoorLock::Attributes::EnablePrivacyModeButton::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeLocalProgrammingFeaturesWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))completionHandler
{
    new MTRDoorLockLocalProgrammingFeaturesAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = DoorLock::Attributes::LocalProgrammingFeatures::TypeInfo;
            auto successFn = Callback<DoorLockLocalProgrammingFeaturesAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeLocalProgrammingFeaturesWithValue:(NSNumber * _Nonnull)value
                                      completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeLocalProgrammingFeaturesWithValue:(NSNumber * _Nonnull) value
                                                   params:nil
                                        completionHandler:completionHandler];
}
- (void)writeAttributeLocalProgrammingFeaturesWithValue:(NSNumber * _Nonnull)value
                                                 params:(MTRWriteParams * _Nullable)params
                                      completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = DoorLock::Attributes::LocalProgrammingFeatures::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = static_cast<std::remove_reference_t<decltype(cppValue)>>(value.unsignedCharValue);
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeLocalProgrammingFeaturesWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                                           params:(MTRSubscribeParams * _Nullable)params
                                          subscriptionEstablished:
                                              (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                    reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRDoorLockLocalProgrammingFeaturesAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = DoorLock::Attributes::LocalProgrammingFeatures::TypeInfo;
            auto successFn = Callback<DoorLockLocalProgrammingFeaturesAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRDoorLockLocalProgrammingFeaturesAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeLocalProgrammingFeaturesWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                       endpoint:(NSNumber *)endpoint
                                                          queue:(dispatch_queue_t)queue
                                              completionHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRDoorLockLocalProgrammingFeaturesAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = DoorLock::Attributes::LocalProgrammingFeatures::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<DoorLockLocalProgrammingFeaturesAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeWrongCodeEntryLimitWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = DoorLock::Attributes::WrongCodeEntryLimit::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeWrongCodeEntryLimitWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeWrongCodeEntryLimitWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeWrongCodeEntryLimitWithValue:(NSNumber * _Nonnull)value
                                            params:(MTRWriteParams * _Nullable)params
                                 completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = DoorLock::Attributes::WrongCodeEntryLimit::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedCharValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeWrongCodeEntryLimitWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = DoorLock::Attributes::WrongCodeEntryLimit::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeWrongCodeEntryLimitWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = DoorLock::Attributes::WrongCodeEntryLimit::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeUserCodeTemporaryDisableTimeWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = DoorLock::Attributes::UserCodeTemporaryDisableTime::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeUserCodeTemporaryDisableTimeWithValue:(NSNumber * _Nonnull)value
                                          completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeUserCodeTemporaryDisableTimeWithValue:(NSNumber * _Nonnull) value
                                                       params:nil
                                            completionHandler:completionHandler];
}
- (void)writeAttributeUserCodeTemporaryDisableTimeWithValue:(NSNumber * _Nonnull)value
                                                     params:(MTRWriteParams * _Nullable)params
                                          completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = DoorLock::Attributes::UserCodeTemporaryDisableTime::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedCharValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeUserCodeTemporaryDisableTimeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                                               params:(MTRSubscribeParams * _Nullable)params
                                              subscriptionEstablished:
                                                  (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                        reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                          NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = DoorLock::Attributes::UserCodeTemporaryDisableTime::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeUserCodeTemporaryDisableTimeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                           endpoint:(NSNumber *)endpoint
                                                              queue:(dispatch_queue_t)queue
                                                  completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = DoorLock::Attributes::UserCodeTemporaryDisableTime::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeSendPINOverTheAirWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    new MTRBooleanAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = DoorLock::Attributes::SendPINOverTheAir::TypeInfo;
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeSendPINOverTheAirWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeSendPINOverTheAirWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeSendPINOverTheAirWithValue:(NSNumber * _Nonnull)value
                                          params:(MTRWriteParams * _Nullable)params
                               completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = DoorLock::Attributes::SendPINOverTheAir::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.boolValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeSendPINOverTheAirWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRBooleanAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = DoorLock::Attributes::SendPINOverTheAir::TypeInfo;
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRBooleanAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeSendPINOverTheAirWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBooleanAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = DoorLock::Attributes::SendPINOverTheAir::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeRequirePINforRemoteOperationWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))completionHandler
{
    new MTRBooleanAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = DoorLock::Attributes::RequirePINforRemoteOperation::TypeInfo;
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeRequirePINforRemoteOperationWithValue:(NSNumber * _Nonnull)value
                                          completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeRequirePINforRemoteOperationWithValue:(NSNumber * _Nonnull) value
                                                       params:nil
                                            completionHandler:completionHandler];
}
- (void)writeAttributeRequirePINforRemoteOperationWithValue:(NSNumber * _Nonnull)value
                                                     params:(MTRWriteParams * _Nullable)params
                                          completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = DoorLock::Attributes::RequirePINforRemoteOperation::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.boolValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeRequirePINforRemoteOperationWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                                               params:(MTRSubscribeParams * _Nullable)params
                                              subscriptionEstablished:
                                                  (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                        reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                          NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRBooleanAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = DoorLock::Attributes::RequirePINforRemoteOperation::TypeInfo;
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRBooleanAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeRequirePINforRemoteOperationWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                           endpoint:(NSNumber *)endpoint
                                                              queue:(dispatch_queue_t)queue
                                                  completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))completionHandler
{
    new MTRBooleanAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = DoorLock::Attributes::RequirePINforRemoteOperation::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeExpiringUserTimeoutWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = DoorLock::Attributes::ExpiringUserTimeout::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeExpiringUserTimeoutWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeExpiringUserTimeoutWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeExpiringUserTimeoutWithValue:(NSNumber * _Nonnull)value
                                            params:(MTRWriteParams * _Nullable)params
                                 completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = DoorLock::Attributes::ExpiringUserTimeout::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeExpiringUserTimeoutWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = DoorLock::Attributes::ExpiringUserTimeout::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeExpiringUserTimeoutWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = DoorLock::Attributes::ExpiringUserTimeout::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRDoorLockGeneratedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = DoorLock::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<DoorLockGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRDoorLockGeneratedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = DoorLock::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<DoorLockGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRDoorLockGeneratedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRDoorLockGeneratedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = DoorLock::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<DoorLockGeneratedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRDoorLockAcceptedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = DoorLock::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<DoorLockAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRDoorLockAcceptedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = DoorLock::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<DoorLockAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRDoorLockAcceptedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRDoorLockAcceptedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = DoorLock::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<DoorLockAcceptedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRDoorLockAttributeListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = DoorLock::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<DoorLockAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRDoorLockAttributeListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = DoorLock::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<DoorLockAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRDoorLockAttributeListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRDoorLockAttributeListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = DoorLock::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<DoorLockAttributeListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = DoorLock::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = DoorLock::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = DoorLock::Attributes::FeatureMap::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = DoorLock::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = DoorLock::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::DoorLockCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = DoorLock::Attributes::ClusterRevision::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

@end

@implementation MTRBaseClusterWindowCovering

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = endpoint;
    }
    return self;
}

- (void)upOrOpenWithCompletionHandler:(StatusCompletion)completionHandler
{
    [self upOrOpenWithParams:nil completionHandler:completionHandler];
}
- (void)upOrOpenWithParams:(MTRWindowCoveringClusterUpOrOpenParams * _Nullable)params
         completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            WindowCovering::Commands::UpOrOpen::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::WindowCoveringCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)downOrCloseWithCompletionHandler:(StatusCompletion)completionHandler
{
    [self downOrCloseWithParams:nil completionHandler:completionHandler];
}
- (void)downOrCloseWithParams:(MTRWindowCoveringClusterDownOrCloseParams * _Nullable)params
            completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            WindowCovering::Commands::DownOrClose::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::WindowCoveringCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)stopMotionWithCompletionHandler:(StatusCompletion)completionHandler
{
    [self stopMotionWithParams:nil completionHandler:completionHandler];
}
- (void)stopMotionWithParams:(MTRWindowCoveringClusterStopMotionParams * _Nullable)params
           completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            WindowCovering::Commands::StopMotion::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::WindowCoveringCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)goToLiftValueWithParams:(MTRWindowCoveringClusterGoToLiftValueParams *)params
              completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            WindowCovering::Commands::GoToLiftValue::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.liftValue = params.liftValue.unsignedShortValue;

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::WindowCoveringCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)goToLiftPercentageWithParams:(MTRWindowCoveringClusterGoToLiftPercentageParams *)params
                   completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            WindowCovering::Commands::GoToLiftPercentage::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.liftPercent100thsValue = params.liftPercent100thsValue.unsignedShortValue;

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::WindowCoveringCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)goToTiltValueWithParams:(MTRWindowCoveringClusterGoToTiltValueParams *)params
              completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            WindowCovering::Commands::GoToTiltValue::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.tiltValue = params.tiltValue.unsignedShortValue;

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::WindowCoveringCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)goToTiltPercentageWithParams:(MTRWindowCoveringClusterGoToTiltPercentageParams *)params
                   completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            WindowCovering::Commands::GoToTiltPercentage::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.tiltPercent100thsValue = params.tiltPercent100thsValue.unsignedShortValue;

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::WindowCoveringCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)readAttributeTypeWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRWindowCoveringClusterTypeAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = WindowCovering::Attributes::Type::TypeInfo;
            auto successFn = Callback<WindowCoveringClusterTypeAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::WindowCoveringCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeTypeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                       params:(MTRSubscribeParams * _Nullable)params
                      subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRWindowCoveringClusterTypeAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = WindowCovering::Attributes::Type::TypeInfo;
            auto successFn = Callback<WindowCoveringClusterTypeAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::WindowCoveringCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRWindowCoveringClusterTypeAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeTypeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                   endpoint:(NSNumber *)endpoint
                                      queue:(dispatch_queue_t)queue
                          completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRWindowCoveringClusterTypeAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WindowCovering::Attributes::Type::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<WindowCoveringClusterTypeAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributePhysicalClosedLimitLiftWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = WindowCovering::Attributes::PhysicalClosedLimitLift::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::WindowCoveringCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributePhysicalClosedLimitLiftWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                     maxInterval:(NSNumber * _Nonnull)maxInterval
                                                          params:(MTRSubscribeParams * _Nullable)params
                                         subscriptionEstablished:
                                             (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                   reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = WindowCovering::Attributes::PhysicalClosedLimitLift::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::WindowCoveringCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributePhysicalClosedLimitLiftWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                             completionHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = WindowCovering::Attributes::PhysicalClosedLimitLift::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributePhysicalClosedLimitTiltWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = WindowCovering::Attributes::PhysicalClosedLimitTilt::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::WindowCoveringCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributePhysicalClosedLimitTiltWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                     maxInterval:(NSNumber * _Nonnull)maxInterval
                                                          params:(MTRSubscribeParams * _Nullable)params
                                         subscriptionEstablished:
                                             (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                   reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = WindowCovering::Attributes::PhysicalClosedLimitTilt::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::WindowCoveringCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributePhysicalClosedLimitTiltWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                             completionHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = WindowCovering::Attributes::PhysicalClosedLimitTilt::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeCurrentPositionLiftWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = WindowCovering::Attributes::CurrentPositionLift::TypeInfo;
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::WindowCoveringCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeCurrentPositionLiftWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = WindowCovering::Attributes::CurrentPositionLift::TypeInfo;
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::WindowCoveringCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeCurrentPositionLiftWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = WindowCovering::Attributes::CurrentPositionLift::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeCurrentPositionTiltWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = WindowCovering::Attributes::CurrentPositionTilt::TypeInfo;
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::WindowCoveringCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeCurrentPositionTiltWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = WindowCovering::Attributes::CurrentPositionTilt::TypeInfo;
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::WindowCoveringCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeCurrentPositionTiltWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = WindowCovering::Attributes::CurrentPositionTilt::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeNumberOfActuationsLiftWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = WindowCovering::Attributes::NumberOfActuationsLift::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::WindowCoveringCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeNumberOfActuationsLiftWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                                         params:(MTRSubscribeParams * _Nullable)params
                                        subscriptionEstablished:
                                            (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                  reportHandler:
                                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = WindowCovering::Attributes::NumberOfActuationsLift::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::WindowCoveringCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeNumberOfActuationsLiftWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                            completionHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = WindowCovering::Attributes::NumberOfActuationsLift::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeNumberOfActuationsTiltWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = WindowCovering::Attributes::NumberOfActuationsTilt::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::WindowCoveringCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeNumberOfActuationsTiltWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                                         params:(MTRSubscribeParams * _Nullable)params
                                        subscriptionEstablished:
                                            (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                  reportHandler:
                                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = WindowCovering::Attributes::NumberOfActuationsTilt::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::WindowCoveringCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeNumberOfActuationsTiltWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                            completionHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = WindowCovering::Attributes::NumberOfActuationsTilt::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeConfigStatusWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRWindowCoveringConfigStatusAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = WindowCovering::Attributes::ConfigStatus::TypeInfo;
            auto successFn = Callback<WindowCoveringConfigStatusAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::WindowCoveringCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeConfigStatusWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRWindowCoveringConfigStatusAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = WindowCovering::Attributes::ConfigStatus::TypeInfo;
            auto successFn = Callback<WindowCoveringConfigStatusAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::WindowCoveringCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRWindowCoveringConfigStatusAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeConfigStatusWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRWindowCoveringConfigStatusAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WindowCovering::Attributes::ConfigStatus::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<WindowCoveringConfigStatusAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeCurrentPositionLiftPercentageWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                            NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = WindowCovering::Attributes::CurrentPositionLiftPercentage::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::WindowCoveringCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeCurrentPositionLiftPercentageWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                params:(MTRSubscribeParams * _Nullable)params
                                               subscriptionEstablished:
                                                   (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                         reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = WindowCovering::Attributes::CurrentPositionLiftPercentage::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::WindowCoveringCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeCurrentPositionLiftPercentageWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                            endpoint:(NSNumber *)endpoint
                                                               queue:(dispatch_queue_t)queue
                                                   completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = WindowCovering::Attributes::CurrentPositionLiftPercentage::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeCurrentPositionTiltPercentageWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                            NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = WindowCovering::Attributes::CurrentPositionTiltPercentage::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::WindowCoveringCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeCurrentPositionTiltPercentageWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                params:(MTRSubscribeParams * _Nullable)params
                                               subscriptionEstablished:
                                                   (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                         reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = WindowCovering::Attributes::CurrentPositionTiltPercentage::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::WindowCoveringCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeCurrentPositionTiltPercentageWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                            endpoint:(NSNumber *)endpoint
                                                               queue:(dispatch_queue_t)queue
                                                   completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = WindowCovering::Attributes::CurrentPositionTiltPercentage::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeOperationalStatusWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    new MTRWindowCoveringOperationalStatusAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = WindowCovering::Attributes::OperationalStatus::TypeInfo;
            auto successFn = Callback<WindowCoveringOperationalStatusAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::WindowCoveringCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeOperationalStatusWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRWindowCoveringOperationalStatusAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = WindowCovering::Attributes::OperationalStatus::TypeInfo;
            auto successFn = Callback<WindowCoveringOperationalStatusAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::WindowCoveringCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRWindowCoveringOperationalStatusAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeOperationalStatusWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRWindowCoveringOperationalStatusAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WindowCovering::Attributes::OperationalStatus::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<WindowCoveringOperationalStatusAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeTargetPositionLiftPercent100thsWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                              NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = WindowCovering::Attributes::TargetPositionLiftPercent100ths::TypeInfo;
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::WindowCoveringCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeTargetPositionLiftPercent100thsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                  params:(MTRSubscribeParams * _Nullable)params
                                                 subscriptionEstablished:
                                                     (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                           reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                             NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = WindowCovering::Attributes::TargetPositionLiftPercent100ths::TypeInfo;
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::WindowCoveringCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeTargetPositionLiftPercent100thsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                              endpoint:(NSNumber *)endpoint
                                                                 queue:(dispatch_queue_t)queue
                                                     completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = WindowCovering::Attributes::TargetPositionLiftPercent100ths::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeTargetPositionTiltPercent100thsWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                              NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = WindowCovering::Attributes::TargetPositionTiltPercent100ths::TypeInfo;
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::WindowCoveringCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeTargetPositionTiltPercent100thsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                  params:(MTRSubscribeParams * _Nullable)params
                                                 subscriptionEstablished:
                                                     (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                           reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                             NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = WindowCovering::Attributes::TargetPositionTiltPercent100ths::TypeInfo;
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::WindowCoveringCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeTargetPositionTiltPercent100thsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                              endpoint:(NSNumber *)endpoint
                                                                 queue:(dispatch_queue_t)queue
                                                     completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = WindowCovering::Attributes::TargetPositionTiltPercent100ths::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeEndProductTypeWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    new MTRWindowCoveringClusterEndProductTypeAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = WindowCovering::Attributes::EndProductType::TypeInfo;
            auto successFn = Callback<WindowCoveringClusterEndProductTypeAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::WindowCoveringCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeEndProductTypeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRWindowCoveringClusterEndProductTypeAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = WindowCovering::Attributes::EndProductType::TypeInfo;
            auto successFn = Callback<WindowCoveringClusterEndProductTypeAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::WindowCoveringCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRWindowCoveringClusterEndProductTypeAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeEndProductTypeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRWindowCoveringClusterEndProductTypeAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WindowCovering::Attributes::EndProductType::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<WindowCoveringClusterEndProductTypeAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeCurrentPositionLiftPercent100thsWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                               NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = WindowCovering::Attributes::CurrentPositionLiftPercent100ths::TypeInfo;
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::WindowCoveringCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeCurrentPositionLiftPercent100thsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                              maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                   params:(MTRSubscribeParams * _Nullable)params
                                                  subscriptionEstablished:
                                                      (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                            reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                              NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = WindowCovering::Attributes::CurrentPositionLiftPercent100ths::TypeInfo;
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::WindowCoveringCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeCurrentPositionLiftPercent100thsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                               endpoint:(NSNumber *)endpoint
                                                                  queue:(dispatch_queue_t)queue
                                                      completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                            NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = WindowCovering::Attributes::CurrentPositionLiftPercent100ths::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeCurrentPositionTiltPercent100thsWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                               NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = WindowCovering::Attributes::CurrentPositionTiltPercent100ths::TypeInfo;
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::WindowCoveringCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeCurrentPositionTiltPercent100thsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                              maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                   params:(MTRSubscribeParams * _Nullable)params
                                                  subscriptionEstablished:
                                                      (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                            reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                              NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = WindowCovering::Attributes::CurrentPositionTiltPercent100ths::TypeInfo;
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::WindowCoveringCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeCurrentPositionTiltPercent100thsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                               endpoint:(NSNumber *)endpoint
                                                                  queue:(dispatch_queue_t)queue
                                                      completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                            NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = WindowCovering::Attributes::CurrentPositionTiltPercent100ths::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeInstalledOpenLimitLiftWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = WindowCovering::Attributes::InstalledOpenLimitLift::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::WindowCoveringCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeInstalledOpenLimitLiftWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                                         params:(MTRSubscribeParams * _Nullable)params
                                        subscriptionEstablished:
                                            (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                  reportHandler:
                                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = WindowCovering::Attributes::InstalledOpenLimitLift::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::WindowCoveringCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeInstalledOpenLimitLiftWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                            completionHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = WindowCovering::Attributes::InstalledOpenLimitLift::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeInstalledClosedLimitLiftWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = WindowCovering::Attributes::InstalledClosedLimitLift::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::WindowCoveringCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeInstalledClosedLimitLiftWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                                           params:(MTRSubscribeParams * _Nullable)params
                                          subscriptionEstablished:
                                              (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                    reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = WindowCovering::Attributes::InstalledClosedLimitLift::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::WindowCoveringCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeInstalledClosedLimitLiftWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                       endpoint:(NSNumber *)endpoint
                                                          queue:(dispatch_queue_t)queue
                                              completionHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = WindowCovering::Attributes::InstalledClosedLimitLift::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeInstalledOpenLimitTiltWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = WindowCovering::Attributes::InstalledOpenLimitTilt::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::WindowCoveringCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeInstalledOpenLimitTiltWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                                         params:(MTRSubscribeParams * _Nullable)params
                                        subscriptionEstablished:
                                            (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                  reportHandler:
                                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = WindowCovering::Attributes::InstalledOpenLimitTilt::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::WindowCoveringCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeInstalledOpenLimitTiltWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                            completionHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = WindowCovering::Attributes::InstalledOpenLimitTilt::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeInstalledClosedLimitTiltWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = WindowCovering::Attributes::InstalledClosedLimitTilt::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::WindowCoveringCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeInstalledClosedLimitTiltWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                                           params:(MTRSubscribeParams * _Nullable)params
                                          subscriptionEstablished:
                                              (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                    reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = WindowCovering::Attributes::InstalledClosedLimitTilt::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::WindowCoveringCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeInstalledClosedLimitTiltWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                       endpoint:(NSNumber *)endpoint
                                                          queue:(dispatch_queue_t)queue
                                              completionHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = WindowCovering::Attributes::InstalledClosedLimitTilt::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeModeWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRWindowCoveringModeAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = WindowCovering::Attributes::Mode::TypeInfo;
            auto successFn = Callback<WindowCoveringModeAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::WindowCoveringCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeModeWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeModeWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeModeWithValue:(NSNumber * _Nonnull)value
                             params:(MTRWriteParams * _Nullable)params
                  completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = WindowCovering::Attributes::Mode::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = static_cast<std::remove_reference_t<decltype(cppValue)>>(value.unsignedCharValue);
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::WindowCoveringCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeModeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                       params:(MTRSubscribeParams * _Nullable)params
                      subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRWindowCoveringModeAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = WindowCovering::Attributes::Mode::TypeInfo;
            auto successFn = Callback<WindowCoveringModeAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::WindowCoveringCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRWindowCoveringModeAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeModeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                   endpoint:(NSNumber *)endpoint
                                      queue:(dispatch_queue_t)queue
                          completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRWindowCoveringModeAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = WindowCovering::Attributes::Mode::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<WindowCoveringModeAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeSafetyStatusWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRWindowCoveringSafetyStatusAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = WindowCovering::Attributes::SafetyStatus::TypeInfo;
            auto successFn = Callback<WindowCoveringSafetyStatusAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::WindowCoveringCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeSafetyStatusWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRWindowCoveringSafetyStatusAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = WindowCovering::Attributes::SafetyStatus::TypeInfo;
            auto successFn = Callback<WindowCoveringSafetyStatusAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::WindowCoveringCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRWindowCoveringSafetyStatusAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeSafetyStatusWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRWindowCoveringSafetyStatusAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WindowCovering::Attributes::SafetyStatus::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<WindowCoveringSafetyStatusAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRWindowCoveringGeneratedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = WindowCovering::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<WindowCoveringGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::WindowCoveringCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRWindowCoveringGeneratedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = WindowCovering::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<WindowCoveringGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::WindowCoveringCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRWindowCoveringGeneratedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRWindowCoveringGeneratedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WindowCovering::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<WindowCoveringGeneratedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRWindowCoveringAcceptedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = WindowCovering::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<WindowCoveringAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::WindowCoveringCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRWindowCoveringAcceptedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = WindowCovering::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<WindowCoveringAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::WindowCoveringCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRWindowCoveringAcceptedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRWindowCoveringAcceptedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WindowCovering::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<WindowCoveringAcceptedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRWindowCoveringAttributeListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = WindowCovering::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<WindowCoveringAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::WindowCoveringCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRWindowCoveringAttributeListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = WindowCovering::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<WindowCoveringAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::WindowCoveringCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRWindowCoveringAttributeListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRWindowCoveringAttributeListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WindowCovering::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<WindowCoveringAttributeListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = WindowCovering::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::WindowCoveringCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = WindowCovering::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::WindowCoveringCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = WindowCovering::Attributes::FeatureMap::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = WindowCovering::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::WindowCoveringCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = WindowCovering::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::WindowCoveringCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = WindowCovering::Attributes::ClusterRevision::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

@end

@implementation MTRBaseClusterBarrierControl

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = endpoint;
    }
    return self;
}

- (void)barrierControlGoToPercentWithParams:(MTRBarrierControlClusterBarrierControlGoToPercentParams *)params
                          completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            BarrierControl::Commands::BarrierControlGoToPercent::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.percentOpen = params.percentOpen.unsignedCharValue;

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BarrierControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)barrierControlStopWithCompletionHandler:(StatusCompletion)completionHandler
{
    [self barrierControlStopWithParams:nil completionHandler:completionHandler];
}
- (void)barrierControlStopWithParams:(MTRBarrierControlClusterBarrierControlStopParams * _Nullable)params
                   completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            BarrierControl::Commands::BarrierControlStop::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BarrierControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)readAttributeBarrierMovingStateWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                 NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BarrierControl::Attributes::BarrierMovingState::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BarrierControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeBarrierMovingStateWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                maxInterval:(NSNumber * _Nonnull)maxInterval
                                                     params:(MTRSubscribeParams * _Nullable)params
                                    subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                              reportHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BarrierControl::Attributes::BarrierMovingState::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BarrierControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeBarrierMovingStateWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                        completionHandler:
                                            (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = BarrierControl::Attributes::BarrierMovingState::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeBarrierSafetyStatusWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BarrierControl::Attributes::BarrierSafetyStatus::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BarrierControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeBarrierSafetyStatusWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BarrierControl::Attributes::BarrierSafetyStatus::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BarrierControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeBarrierSafetyStatusWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = BarrierControl::Attributes::BarrierSafetyStatus::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeBarrierCapabilitiesWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BarrierControl::Attributes::BarrierCapabilities::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BarrierControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeBarrierCapabilitiesWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BarrierControl::Attributes::BarrierCapabilities::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BarrierControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeBarrierCapabilitiesWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = BarrierControl::Attributes::BarrierCapabilities::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeBarrierOpenEventsWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BarrierControl::Attributes::BarrierOpenEvents::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BarrierControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeBarrierOpenEventsWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeBarrierOpenEventsWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeBarrierOpenEventsWithValue:(NSNumber * _Nonnull)value
                                          params:(MTRWriteParams * _Nullable)params
                               completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = BarrierControl::Attributes::BarrierOpenEvents::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BarrierControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeBarrierOpenEventsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BarrierControl::Attributes::BarrierOpenEvents::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BarrierControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeBarrierOpenEventsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = BarrierControl::Attributes::BarrierOpenEvents::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeBarrierCloseEventsWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                 NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BarrierControl::Attributes::BarrierCloseEvents::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BarrierControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeBarrierCloseEventsWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeBarrierCloseEventsWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeBarrierCloseEventsWithValue:(NSNumber * _Nonnull)value
                                           params:(MTRWriteParams * _Nullable)params
                                completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = BarrierControl::Attributes::BarrierCloseEvents::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BarrierControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeBarrierCloseEventsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                maxInterval:(NSNumber * _Nonnull)maxInterval
                                                     params:(MTRSubscribeParams * _Nullable)params
                                    subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                              reportHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BarrierControl::Attributes::BarrierCloseEvents::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BarrierControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeBarrierCloseEventsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                        completionHandler:
                                            (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = BarrierControl::Attributes::BarrierCloseEvents::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeBarrierCommandOpenEventsWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BarrierControl::Attributes::BarrierCommandOpenEvents::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BarrierControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeBarrierCommandOpenEventsWithValue:(NSNumber * _Nonnull)value
                                      completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeBarrierCommandOpenEventsWithValue:(NSNumber * _Nonnull) value
                                                   params:nil
                                        completionHandler:completionHandler];
}
- (void)writeAttributeBarrierCommandOpenEventsWithValue:(NSNumber * _Nonnull)value
                                                 params:(MTRWriteParams * _Nullable)params
                                      completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = BarrierControl::Attributes::BarrierCommandOpenEvents::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BarrierControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeBarrierCommandOpenEventsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                                           params:(MTRSubscribeParams * _Nullable)params
                                          subscriptionEstablished:
                                              (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                    reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BarrierControl::Attributes::BarrierCommandOpenEvents::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BarrierControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeBarrierCommandOpenEventsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                       endpoint:(NSNumber *)endpoint
                                                          queue:(dispatch_queue_t)queue
                                              completionHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = BarrierControl::Attributes::BarrierCommandOpenEvents::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeBarrierCommandCloseEventsWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BarrierControl::Attributes::BarrierCommandCloseEvents::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BarrierControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeBarrierCommandCloseEventsWithValue:(NSNumber * _Nonnull)value
                                       completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeBarrierCommandCloseEventsWithValue:(NSNumber * _Nonnull) value
                                                    params:nil
                                         completionHandler:completionHandler];
}
- (void)writeAttributeBarrierCommandCloseEventsWithValue:(NSNumber * _Nonnull)value
                                                  params:(MTRWriteParams * _Nullable)params
                                       completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = BarrierControl::Attributes::BarrierCommandCloseEvents::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BarrierControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeBarrierCommandCloseEventsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                                            params:(MTRSubscribeParams * _Nullable)params
                                           subscriptionEstablished:
                                               (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                     reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BarrierControl::Attributes::BarrierCommandCloseEvents::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BarrierControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeBarrierCommandCloseEventsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                        endpoint:(NSNumber *)endpoint
                                                           queue:(dispatch_queue_t)queue
                                               completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = BarrierControl::Attributes::BarrierCommandCloseEvents::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeBarrierOpenPeriodWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BarrierControl::Attributes::BarrierOpenPeriod::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BarrierControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeBarrierOpenPeriodWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeBarrierOpenPeriodWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeBarrierOpenPeriodWithValue:(NSNumber * _Nonnull)value
                                          params:(MTRWriteParams * _Nullable)params
                               completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = BarrierControl::Attributes::BarrierOpenPeriod::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BarrierControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeBarrierOpenPeriodWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BarrierControl::Attributes::BarrierOpenPeriod::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BarrierControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeBarrierOpenPeriodWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = BarrierControl::Attributes::BarrierOpenPeriod::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeBarrierClosePeriodWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                 NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BarrierControl::Attributes::BarrierClosePeriod::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BarrierControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeBarrierClosePeriodWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeBarrierClosePeriodWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeBarrierClosePeriodWithValue:(NSNumber * _Nonnull)value
                                           params:(MTRWriteParams * _Nullable)params
                                completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = BarrierControl::Attributes::BarrierClosePeriod::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BarrierControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeBarrierClosePeriodWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                maxInterval:(NSNumber * _Nonnull)maxInterval
                                                     params:(MTRSubscribeParams * _Nullable)params
                                    subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                              reportHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BarrierControl::Attributes::BarrierClosePeriod::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BarrierControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeBarrierClosePeriodWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                        completionHandler:
                                            (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = BarrierControl::Attributes::BarrierClosePeriod::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeBarrierPositionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BarrierControl::Attributes::BarrierPosition::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BarrierControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeBarrierPositionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BarrierControl::Attributes::BarrierPosition::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BarrierControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeBarrierPositionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = BarrierControl::Attributes::BarrierPosition::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRBarrierControlGeneratedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BarrierControl::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<BarrierControlGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BarrierControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRBarrierControlGeneratedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BarrierControl::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<BarrierControlGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BarrierControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRBarrierControlGeneratedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBarrierControlGeneratedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BarrierControl::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<BarrierControlGeneratedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRBarrierControlAcceptedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BarrierControl::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<BarrierControlAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BarrierControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRBarrierControlAcceptedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BarrierControl::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<BarrierControlAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BarrierControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRBarrierControlAcceptedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBarrierControlAcceptedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BarrierControl::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<BarrierControlAcceptedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBarrierControlAttributeListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BarrierControl::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<BarrierControlAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BarrierControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRBarrierControlAttributeListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BarrierControl::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<BarrierControlAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BarrierControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRBarrierControlAttributeListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBarrierControlAttributeListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BarrierControl::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<BarrierControlAttributeListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BarrierControl::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BarrierControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BarrierControl::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BarrierControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = BarrierControl::Attributes::FeatureMap::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BarrierControl::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BarrierControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BarrierControl::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BarrierControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = BarrierControl::Attributes::ClusterRevision::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

@end

@implementation MTRBaseClusterPumpConfigurationAndControl

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = endpoint;
    }
    return self;
}

- (void)readAttributeMaxPressureWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PumpConfigurationAndControl::Attributes::MaxPressure::TypeInfo;
            auto successFn = Callback<NullableInt16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PumpConfigurationAndControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeMaxPressureWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PumpConfigurationAndControl::Attributes::MaxPressure::TypeInfo;
            auto successFn = Callback<NullableInt16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PumpConfigurationAndControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeMaxPressureWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = PumpConfigurationAndControl::Attributes::MaxPressure::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeMaxSpeedWithCompletionHandler:(void (^)(
                                                       NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PumpConfigurationAndControl::Attributes::MaxSpeed::TypeInfo;
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PumpConfigurationAndControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeMaxSpeedWithMinInterval:(NSNumber * _Nonnull)minInterval
                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                           params:(MTRSubscribeParams * _Nullable)params
                          subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PumpConfigurationAndControl::Attributes::MaxSpeed::TypeInfo;
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PumpConfigurationAndControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeMaxSpeedWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                       endpoint:(NSNumber *)endpoint
                                          queue:(dispatch_queue_t)queue
                              completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = PumpConfigurationAndControl::Attributes::MaxSpeed::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeMaxFlowWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PumpConfigurationAndControl::Attributes::MaxFlow::TypeInfo;
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PumpConfigurationAndControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeMaxFlowWithMinInterval:(NSNumber * _Nonnull)minInterval
                                     maxInterval:(NSNumber * _Nonnull)maxInterval
                                          params:(MTRSubscribeParams * _Nullable)params
                         subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                   reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PumpConfigurationAndControl::Attributes::MaxFlow::TypeInfo;
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PumpConfigurationAndControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeMaxFlowWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                      endpoint:(NSNumber *)endpoint
                                         queue:(dispatch_queue_t)queue
                             completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = PumpConfigurationAndControl::Attributes::MaxFlow::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeMinConstPressureWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PumpConfigurationAndControl::Attributes::MinConstPressure::TypeInfo;
            auto successFn = Callback<NullableInt16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PumpConfigurationAndControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeMinConstPressureWithMinInterval:(NSNumber * _Nonnull)minInterval
                                              maxInterval:(NSNumber * _Nonnull)maxInterval
                                                   params:(MTRSubscribeParams * _Nullable)params
                                  subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                            reportHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PumpConfigurationAndControl::Attributes::MinConstPressure::TypeInfo;
            auto successFn = Callback<NullableInt16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PumpConfigurationAndControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeMinConstPressureWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = PumpConfigurationAndControl::Attributes::MinConstPressure::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeMaxConstPressureWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PumpConfigurationAndControl::Attributes::MaxConstPressure::TypeInfo;
            auto successFn = Callback<NullableInt16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PumpConfigurationAndControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeMaxConstPressureWithMinInterval:(NSNumber * _Nonnull)minInterval
                                              maxInterval:(NSNumber * _Nonnull)maxInterval
                                                   params:(MTRSubscribeParams * _Nullable)params
                                  subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                            reportHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PumpConfigurationAndControl::Attributes::MaxConstPressure::TypeInfo;
            auto successFn = Callback<NullableInt16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PumpConfigurationAndControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeMaxConstPressureWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = PumpConfigurationAndControl::Attributes::MaxConstPressure::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeMinCompPressureWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PumpConfigurationAndControl::Attributes::MinCompPressure::TypeInfo;
            auto successFn = Callback<NullableInt16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PumpConfigurationAndControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeMinCompPressureWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PumpConfigurationAndControl::Attributes::MinCompPressure::TypeInfo;
            auto successFn = Callback<NullableInt16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PumpConfigurationAndControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeMinCompPressureWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = PumpConfigurationAndControl::Attributes::MinCompPressure::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeMaxCompPressureWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PumpConfigurationAndControl::Attributes::MaxCompPressure::TypeInfo;
            auto successFn = Callback<NullableInt16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PumpConfigurationAndControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeMaxCompPressureWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PumpConfigurationAndControl::Attributes::MaxCompPressure::TypeInfo;
            auto successFn = Callback<NullableInt16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PumpConfigurationAndControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeMaxCompPressureWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = PumpConfigurationAndControl::Attributes::MaxCompPressure::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeMinConstSpeedWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PumpConfigurationAndControl::Attributes::MinConstSpeed::TypeInfo;
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PumpConfigurationAndControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeMinConstSpeedWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PumpConfigurationAndControl::Attributes::MinConstSpeed::TypeInfo;
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PumpConfigurationAndControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeMinConstSpeedWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = PumpConfigurationAndControl::Attributes::MinConstSpeed::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeMaxConstSpeedWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PumpConfigurationAndControl::Attributes::MaxConstSpeed::TypeInfo;
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PumpConfigurationAndControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeMaxConstSpeedWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PumpConfigurationAndControl::Attributes::MaxConstSpeed::TypeInfo;
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PumpConfigurationAndControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeMaxConstSpeedWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = PumpConfigurationAndControl::Attributes::MaxConstSpeed::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeMinConstFlowWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PumpConfigurationAndControl::Attributes::MinConstFlow::TypeInfo;
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PumpConfigurationAndControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeMinConstFlowWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PumpConfigurationAndControl::Attributes::MinConstFlow::TypeInfo;
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PumpConfigurationAndControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeMinConstFlowWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = PumpConfigurationAndControl::Attributes::MinConstFlow::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeMaxConstFlowWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PumpConfigurationAndControl::Attributes::MaxConstFlow::TypeInfo;
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PumpConfigurationAndControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeMaxConstFlowWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PumpConfigurationAndControl::Attributes::MaxConstFlow::TypeInfo;
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PumpConfigurationAndControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeMaxConstFlowWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = PumpConfigurationAndControl::Attributes::MaxConstFlow::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeMinConstTempWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PumpConfigurationAndControl::Attributes::MinConstTemp::TypeInfo;
            auto successFn = Callback<NullableInt16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PumpConfigurationAndControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeMinConstTempWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PumpConfigurationAndControl::Attributes::MinConstTemp::TypeInfo;
            auto successFn = Callback<NullableInt16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PumpConfigurationAndControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeMinConstTempWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = PumpConfigurationAndControl::Attributes::MinConstTemp::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeMaxConstTempWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PumpConfigurationAndControl::Attributes::MaxConstTemp::TypeInfo;
            auto successFn = Callback<NullableInt16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PumpConfigurationAndControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeMaxConstTempWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PumpConfigurationAndControl::Attributes::MaxConstTemp::TypeInfo;
            auto successFn = Callback<NullableInt16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PumpConfigurationAndControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeMaxConstTempWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = PumpConfigurationAndControl::Attributes::MaxConstTemp::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributePumpStatusWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRPumpConfigurationAndControlPumpStatusAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PumpConfigurationAndControl::Attributes::PumpStatus::TypeInfo;
            auto successFn = Callback<PumpConfigurationAndControlPumpStatusAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PumpConfigurationAndControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributePumpStatusWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRPumpConfigurationAndControlPumpStatusAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PumpConfigurationAndControl::Attributes::PumpStatus::TypeInfo;
            auto successFn = Callback<PumpConfigurationAndControlPumpStatusAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PumpConfigurationAndControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRPumpConfigurationAndControlPumpStatusAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributePumpStatusWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRPumpConfigurationAndControlPumpStatusAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PumpConfigurationAndControl::Attributes::PumpStatus::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<PumpConfigurationAndControlPumpStatusAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEffectiveOperationModeWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completionHandler
{
    new MTRPumpConfigurationAndControlClusterPumpOperationModeAttributeCallbackBridge(self.callbackQueue, self.device,
        completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PumpConfigurationAndControl::Attributes::EffectiveOperationMode::TypeInfo;
            auto successFn
                = Callback<PumpConfigurationAndControlClusterPumpOperationModeAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PumpConfigurationAndControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeEffectiveOperationModeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                                         params:(MTRSubscribeParams * _Nullable)params
                                        subscriptionEstablished:
                                            (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                  reportHandler:
                                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRPumpConfigurationAndControlClusterPumpOperationModeAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PumpConfigurationAndControl::Attributes::EffectiveOperationMode::TypeInfo;
            auto successFn
                = Callback<PumpConfigurationAndControlClusterPumpOperationModeAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PumpConfigurationAndControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRPumpConfigurationAndControlClusterPumpOperationModeAttributeCallbackSubscriptionBridge::
                    OnSubscriptionEstablished,
                nil, params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeEffectiveOperationModeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                            completionHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRPumpConfigurationAndControlClusterPumpOperationModeAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PumpConfigurationAndControl::Attributes::EffectiveOperationMode::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn
                    = Callback<PumpConfigurationAndControlClusterPumpOperationModeAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEffectiveControlModeWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRPumpConfigurationAndControlClusterPumpControlModeAttributeCallbackBridge(self.callbackQueue, self.device,
        completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PumpConfigurationAndControl::Attributes::EffectiveControlMode::TypeInfo;
            auto successFn = Callback<PumpConfigurationAndControlClusterPumpControlModeAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PumpConfigurationAndControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeEffectiveControlModeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRPumpConfigurationAndControlClusterPumpControlModeAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PumpConfigurationAndControl::Attributes::EffectiveControlMode::TypeInfo;
            auto successFn = Callback<PumpConfigurationAndControlClusterPumpControlModeAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PumpConfigurationAndControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRPumpConfigurationAndControlClusterPumpControlModeAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished,
                nil, params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeEffectiveControlModeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRPumpConfigurationAndControlClusterPumpControlModeAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PumpConfigurationAndControl::Attributes::EffectiveControlMode::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn
                    = Callback<PumpConfigurationAndControlClusterPumpControlModeAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeCapacityWithCompletionHandler:(void (^)(
                                                       NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PumpConfigurationAndControl::Attributes::Capacity::TypeInfo;
            auto successFn = Callback<NullableInt16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PumpConfigurationAndControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeCapacityWithMinInterval:(NSNumber * _Nonnull)minInterval
                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                           params:(MTRSubscribeParams * _Nullable)params
                          subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PumpConfigurationAndControl::Attributes::Capacity::TypeInfo;
            auto successFn = Callback<NullableInt16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PumpConfigurationAndControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeCapacityWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                       endpoint:(NSNumber *)endpoint
                                          queue:(dispatch_queue_t)queue
                              completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = PumpConfigurationAndControl::Attributes::Capacity::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeSpeedWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PumpConfigurationAndControl::Attributes::Speed::TypeInfo;
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PumpConfigurationAndControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeSpeedWithMinInterval:(NSNumber * _Nonnull)minInterval
                                   maxInterval:(NSNumber * _Nonnull)maxInterval
                                        params:(MTRSubscribeParams * _Nullable)params
                       subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PumpConfigurationAndControl::Attributes::Speed::TypeInfo;
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PumpConfigurationAndControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeSpeedWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                    endpoint:(NSNumber *)endpoint
                                       queue:(dispatch_queue_t)queue
                           completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = PumpConfigurationAndControl::Attributes::Speed::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeLifetimeRunningHoursWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRNullableInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PumpConfigurationAndControl::Attributes::LifetimeRunningHours::TypeInfo;
            auto successFn = Callback<NullableInt32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PumpConfigurationAndControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeLifetimeRunningHoursWithValue:(NSNumber * _Nullable)value
                                  completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeLifetimeRunningHoursWithValue:(NSNumber * _Nullable) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeLifetimeRunningHoursWithValue:(NSNumber * _Nullable)value
                                             params:(MTRWriteParams * _Nullable)params
                                  completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = PumpConfigurationAndControl::Attributes::LifetimeRunningHours::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.unsignedIntValue;
            }
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PumpConfigurationAndControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeLifetimeRunningHoursWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PumpConfigurationAndControl::Attributes::LifetimeRunningHours::TypeInfo;
            auto successFn = Callback<NullableInt32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PumpConfigurationAndControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeLifetimeRunningHoursWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = PumpConfigurationAndControl::Attributes::LifetimeRunningHours::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributePowerWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PumpConfigurationAndControl::Attributes::Power::TypeInfo;
            auto successFn = Callback<NullableInt32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PumpConfigurationAndControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributePowerWithMinInterval:(NSNumber * _Nonnull)minInterval
                                   maxInterval:(NSNumber * _Nonnull)maxInterval
                                        params:(MTRSubscribeParams * _Nullable)params
                       subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PumpConfigurationAndControl::Attributes::Power::TypeInfo;
            auto successFn = Callback<NullableInt32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PumpConfigurationAndControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributePowerWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                    endpoint:(NSNumber *)endpoint
                                       queue:(dispatch_queue_t)queue
                           completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = PumpConfigurationAndControl::Attributes::Power::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeLifetimeEnergyConsumedWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completionHandler
{
    new MTRNullableInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PumpConfigurationAndControl::Attributes::LifetimeEnergyConsumed::TypeInfo;
            auto successFn = Callback<NullableInt32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PumpConfigurationAndControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeLifetimeEnergyConsumedWithValue:(NSNumber * _Nullable)value
                                    completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeLifetimeEnergyConsumedWithValue:(NSNumber * _Nullable) value
                                                 params:nil
                                      completionHandler:completionHandler];
}
- (void)writeAttributeLifetimeEnergyConsumedWithValue:(NSNumber * _Nullable)value
                                               params:(MTRWriteParams * _Nullable)params
                                    completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = PumpConfigurationAndControl::Attributes::LifetimeEnergyConsumed::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.unsignedIntValue;
            }
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PumpConfigurationAndControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeLifetimeEnergyConsumedWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                                         params:(MTRSubscribeParams * _Nullable)params
                                        subscriptionEstablished:
                                            (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                  reportHandler:
                                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PumpConfigurationAndControl::Attributes::LifetimeEnergyConsumed::TypeInfo;
            auto successFn = Callback<NullableInt32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PumpConfigurationAndControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeLifetimeEnergyConsumedWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                            completionHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = PumpConfigurationAndControl::Attributes::LifetimeEnergyConsumed::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeOperationModeWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRPumpConfigurationAndControlClusterPumpOperationModeAttributeCallbackBridge(self.callbackQueue, self.device,
        completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PumpConfigurationAndControl::Attributes::OperationMode::TypeInfo;
            auto successFn
                = Callback<PumpConfigurationAndControlClusterPumpOperationModeAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PumpConfigurationAndControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeOperationModeWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeOperationModeWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeOperationModeWithValue:(NSNumber * _Nonnull)value
                                      params:(MTRWriteParams * _Nullable)params
                           completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = PumpConfigurationAndControl::Attributes::OperationMode::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = static_cast<std::remove_reference_t<decltype(cppValue)>>(value.unsignedCharValue);
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PumpConfigurationAndControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeOperationModeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRPumpConfigurationAndControlClusterPumpOperationModeAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PumpConfigurationAndControl::Attributes::OperationMode::TypeInfo;
            auto successFn
                = Callback<PumpConfigurationAndControlClusterPumpOperationModeAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PumpConfigurationAndControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRPumpConfigurationAndControlClusterPumpOperationModeAttributeCallbackSubscriptionBridge::
                    OnSubscriptionEstablished,
                nil, params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeOperationModeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRPumpConfigurationAndControlClusterPumpOperationModeAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PumpConfigurationAndControl::Attributes::OperationMode::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn
                    = Callback<PumpConfigurationAndControlClusterPumpOperationModeAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeControlModeWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRPumpConfigurationAndControlClusterPumpControlModeAttributeCallbackBridge(self.callbackQueue, self.device,
        completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PumpConfigurationAndControl::Attributes::ControlMode::TypeInfo;
            auto successFn = Callback<PumpConfigurationAndControlClusterPumpControlModeAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PumpConfigurationAndControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeControlModeWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeControlModeWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeControlModeWithValue:(NSNumber * _Nonnull)value
                                    params:(MTRWriteParams * _Nullable)params
                         completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = PumpConfigurationAndControl::Attributes::ControlMode::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = static_cast<std::remove_reference_t<decltype(cppValue)>>(value.unsignedCharValue);
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PumpConfigurationAndControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeControlModeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRPumpConfigurationAndControlClusterPumpControlModeAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PumpConfigurationAndControl::Attributes::ControlMode::TypeInfo;
            auto successFn = Callback<PumpConfigurationAndControlClusterPumpControlModeAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PumpConfigurationAndControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRPumpConfigurationAndControlClusterPumpControlModeAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished,
                nil, params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeControlModeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRPumpConfigurationAndControlClusterPumpControlModeAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PumpConfigurationAndControl::Attributes::ControlMode::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn
                    = Callback<PumpConfigurationAndControlClusterPumpControlModeAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRPumpConfigurationAndControlGeneratedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device,
        completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PumpConfigurationAndControl::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn
                = Callback<PumpConfigurationAndControlGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PumpConfigurationAndControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRPumpConfigurationAndControlGeneratedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PumpConfigurationAndControl::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn
                = Callback<PumpConfigurationAndControlGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PumpConfigurationAndControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRPumpConfigurationAndControlGeneratedCommandListListAttributeCallbackSubscriptionBridge::
                    OnSubscriptionEstablished,
                nil, params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRPumpConfigurationAndControlGeneratedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PumpConfigurationAndControl::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn
                    = Callback<PumpConfigurationAndControlGeneratedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRPumpConfigurationAndControlAcceptedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device,
        completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PumpConfigurationAndControl::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<PumpConfigurationAndControlAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PumpConfigurationAndControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRPumpConfigurationAndControlAcceptedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PumpConfigurationAndControl::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<PumpConfigurationAndControlAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PumpConfigurationAndControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRPumpConfigurationAndControlAcceptedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished,
                nil, params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRPumpConfigurationAndControlAcceptedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PumpConfigurationAndControl::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn
                    = Callback<PumpConfigurationAndControlAcceptedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRPumpConfigurationAndControlAttributeListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PumpConfigurationAndControl::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<PumpConfigurationAndControlAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PumpConfigurationAndControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRPumpConfigurationAndControlAttributeListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PumpConfigurationAndControl::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<PumpConfigurationAndControlAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PumpConfigurationAndControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRPumpConfigurationAndControlAttributeListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRPumpConfigurationAndControlAttributeListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PumpConfigurationAndControl::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<PumpConfigurationAndControlAttributeListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PumpConfigurationAndControl::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PumpConfigurationAndControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PumpConfigurationAndControl::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PumpConfigurationAndControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = PumpConfigurationAndControl::Attributes::FeatureMap::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PumpConfigurationAndControl::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PumpConfigurationAndControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PumpConfigurationAndControl::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PumpConfigurationAndControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = PumpConfigurationAndControl::Attributes::ClusterRevision::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

@end

@implementation MTRBaseClusterThermostat

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = endpoint;
    }
    return self;
}

- (void)setpointRaiseLowerWithParams:(MTRThermostatClusterSetpointRaiseLowerParams *)params
                   completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            Thermostat::Commands::SetpointRaiseLower::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.mode = static_cast<std::remove_reference_t<decltype(request.mode)>>(params.mode.unsignedCharValue);
            request.amount = params.amount.charValue;

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)setWeeklyScheduleWithParams:(MTRThermostatClusterSetWeeklyScheduleParams *)params
                  completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            Thermostat::Commands::SetWeeklySchedule::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.numberOfTransitionsForSequence = params.numberOfTransitionsForSequence.unsignedCharValue;
            request.dayOfWeekForSequence = static_cast<std::remove_reference_t<decltype(request.dayOfWeekForSequence)>>(
                params.dayOfWeekForSequence.unsignedCharValue);
            request.modeForSequence
                = static_cast<std::remove_reference_t<decltype(request.modeForSequence)>>(params.modeForSequence.unsignedCharValue);
            {
                using ListType_0 = std::remove_reference_t<decltype(request.transitions)>;
                using ListMemberType_0 = ListMemberTypeGetter<ListType_0>::Type;
                if (params.transitions.count != 0) {
                    auto * listHolder_0 = new ListHolder<ListMemberType_0>(params.transitions.count);
                    if (listHolder_0 == nullptr || listHolder_0->mList == nullptr) {
                        return CHIP_ERROR_INVALID_ARGUMENT;
                    }
                    listFreer.add(listHolder_0);
                    for (size_t i_0 = 0; i_0 < params.transitions.count; ++i_0) {
                        if (![params.transitions[i_0] isKindOfClass:[MTRThermostatClusterThermostatScheduleTransition class]]) {
                            // Wrong kind of value.
                            return CHIP_ERROR_INVALID_ARGUMENT;
                        }
                        auto element_0 = (MTRThermostatClusterThermostatScheduleTransition *) params.transitions[i_0];
                        listHolder_0->mList[i_0].transitionTime = element_0.transitionTime.unsignedShortValue;
                        if (element_0.heatSetpoint == nil) {
                            listHolder_0->mList[i_0].heatSetpoint.SetNull();
                        } else {
                            auto & nonNullValue_2 = listHolder_0->mList[i_0].heatSetpoint.SetNonNull();
                            nonNullValue_2 = element_0.heatSetpoint.shortValue;
                        }
                        if (element_0.coolSetpoint == nil) {
                            listHolder_0->mList[i_0].coolSetpoint.SetNull();
                        } else {
                            auto & nonNullValue_2 = listHolder_0->mList[i_0].coolSetpoint.SetNonNull();
                            nonNullValue_2 = element_0.coolSetpoint.shortValue;
                        }
                    }
                    request.transitions = ListType_0(listHolder_0->mList, params.transitions.count);
                } else {
                    request.transitions = ListType_0();
                }
            }

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)getWeeklyScheduleWithParams:(MTRThermostatClusterGetWeeklyScheduleParams *)params
                  completionHandler:(void (^)(MTRThermostatClusterGetWeeklyScheduleResponseParams * _Nullable data,
                                        NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRThermostatClusterGetWeeklyScheduleResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            Thermostat::Commands::GetWeeklySchedule::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.daysToReturn
                = static_cast<std::remove_reference_t<decltype(request.daysToReturn)>>(params.daysToReturn.unsignedCharValue);
            request.modeToReturn
                = static_cast<std::remove_reference_t<decltype(request.modeToReturn)>>(params.modeToReturn.unsignedCharValue);

            auto successFn = Callback<ThermostatClusterGetWeeklyScheduleResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)clearWeeklyScheduleWithCompletionHandler:(StatusCompletion)completionHandler
{
    [self clearWeeklyScheduleWithParams:nil completionHandler:completionHandler];
}
- (void)clearWeeklyScheduleWithParams:(MTRThermostatClusterClearWeeklyScheduleParams * _Nullable)params
                    completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            Thermostat::Commands::ClearWeeklySchedule::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)readAttributeLocalTemperatureWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Thermostat::Attributes::LocalTemperature::TypeInfo;
            auto successFn = Callback<NullableInt16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeLocalTemperatureWithMinInterval:(NSNumber * _Nonnull)minInterval
                                              maxInterval:(NSNumber * _Nonnull)maxInterval
                                                   params:(MTRSubscribeParams * _Nullable)params
                                  subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                            reportHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Thermostat::Attributes::LocalTemperature::TypeInfo;
            auto successFn = Callback<NullableInt16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeLocalTemperatureWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Thermostat::Attributes::LocalTemperature::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeOutdoorTemperatureWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                 NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Thermostat::Attributes::OutdoorTemperature::TypeInfo;
            auto successFn = Callback<NullableInt16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeOutdoorTemperatureWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                maxInterval:(NSNumber * _Nonnull)maxInterval
                                                     params:(MTRSubscribeParams * _Nullable)params
                                    subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                              reportHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Thermostat::Attributes::OutdoorTemperature::TypeInfo;
            auto successFn = Callback<NullableInt16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeOutdoorTemperatureWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                        completionHandler:
                                            (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Thermostat::Attributes::OutdoorTemperature::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeOccupancyWithCompletionHandler:(void (^)(
                                                        NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Thermostat::Attributes::Occupancy::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeOccupancyWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Thermostat::Attributes::Occupancy::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeOccupancyWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Thermostat::Attributes::Occupancy::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeAbsMinHeatSetpointLimitWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Thermostat::Attributes::AbsMinHeatSetpointLimit::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAbsMinHeatSetpointLimitWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                     maxInterval:(NSNumber * _Nonnull)maxInterval
                                                          params:(MTRSubscribeParams * _Nullable)params
                                         subscriptionEstablished:
                                             (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                   reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Thermostat::Attributes::AbsMinHeatSetpointLimit::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAbsMinHeatSetpointLimitWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                             completionHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Thermostat::Attributes::AbsMinHeatSetpointLimit::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeAbsMaxHeatSetpointLimitWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Thermostat::Attributes::AbsMaxHeatSetpointLimit::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAbsMaxHeatSetpointLimitWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                     maxInterval:(NSNumber * _Nonnull)maxInterval
                                                          params:(MTRSubscribeParams * _Nullable)params
                                         subscriptionEstablished:
                                             (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                   reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Thermostat::Attributes::AbsMaxHeatSetpointLimit::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAbsMaxHeatSetpointLimitWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                             completionHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Thermostat::Attributes::AbsMaxHeatSetpointLimit::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeAbsMinCoolSetpointLimitWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Thermostat::Attributes::AbsMinCoolSetpointLimit::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAbsMinCoolSetpointLimitWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                     maxInterval:(NSNumber * _Nonnull)maxInterval
                                                          params:(MTRSubscribeParams * _Nullable)params
                                         subscriptionEstablished:
                                             (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                   reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Thermostat::Attributes::AbsMinCoolSetpointLimit::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAbsMinCoolSetpointLimitWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                             completionHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Thermostat::Attributes::AbsMinCoolSetpointLimit::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeAbsMaxCoolSetpointLimitWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Thermostat::Attributes::AbsMaxCoolSetpointLimit::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAbsMaxCoolSetpointLimitWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                     maxInterval:(NSNumber * _Nonnull)maxInterval
                                                          params:(MTRSubscribeParams * _Nullable)params
                                         subscriptionEstablished:
                                             (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                   reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Thermostat::Attributes::AbsMaxCoolSetpointLimit::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAbsMaxCoolSetpointLimitWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                             completionHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Thermostat::Attributes::AbsMaxCoolSetpointLimit::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributePICoolingDemandWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Thermostat::Attributes::PICoolingDemand::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributePICoolingDemandWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Thermostat::Attributes::PICoolingDemand::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributePICoolingDemandWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Thermostat::Attributes::PICoolingDemand::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributePIHeatingDemandWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Thermostat::Attributes::PIHeatingDemand::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributePIHeatingDemandWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Thermostat::Attributes::PIHeatingDemand::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributePIHeatingDemandWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Thermostat::Attributes::PIHeatingDemand::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeHVACSystemTypeConfigurationWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                          NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Thermostat::Attributes::HVACSystemTypeConfiguration::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeHVACSystemTypeConfigurationWithValue:(NSNumber * _Nonnull)value
                                         completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeHVACSystemTypeConfigurationWithValue:(NSNumber * _Nonnull) value
                                                      params:nil
                                           completionHandler:completionHandler];
}
- (void)writeAttributeHVACSystemTypeConfigurationWithValue:(NSNumber * _Nonnull)value
                                                    params:(MTRWriteParams * _Nullable)params
                                         completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = Thermostat::Attributes::HVACSystemTypeConfiguration::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedCharValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeHVACSystemTypeConfigurationWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                                              params:(MTRSubscribeParams * _Nullable)params
                                             subscriptionEstablished:
                                                 (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                       reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Thermostat::Attributes::HVACSystemTypeConfiguration::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeHVACSystemTypeConfigurationWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                          endpoint:(NSNumber *)endpoint
                                                             queue:(dispatch_queue_t)queue
                                                 completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Thermostat::Attributes::HVACSystemTypeConfiguration::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeLocalTemperatureCalibrationWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                          NSError * _Nullable error))completionHandler
{
    new MTRInt8sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Thermostat::Attributes::LocalTemperatureCalibration::TypeInfo;
            auto successFn = Callback<Int8sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeLocalTemperatureCalibrationWithValue:(NSNumber * _Nonnull)value
                                         completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeLocalTemperatureCalibrationWithValue:(NSNumber * _Nonnull) value
                                                      params:nil
                                           completionHandler:completionHandler];
}
- (void)writeAttributeLocalTemperatureCalibrationWithValue:(NSNumber * _Nonnull)value
                                                    params:(MTRWriteParams * _Nullable)params
                                         completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = Thermostat::Attributes::LocalTemperatureCalibration::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.charValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeLocalTemperatureCalibrationWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                                              params:(MTRSubscribeParams * _Nullable)params
                                             subscriptionEstablished:
                                                 (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                       reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Thermostat::Attributes::LocalTemperatureCalibration::TypeInfo;
            auto successFn = Callback<Int8sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeLocalTemperatureCalibrationWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                          endpoint:(NSNumber *)endpoint
                                                             queue:(dispatch_queue_t)queue
                                                 completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))completionHandler
{
    new MTRInt8sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Thermostat::Attributes::LocalTemperatureCalibration::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeOccupiedCoolingSetpointWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Thermostat::Attributes::OccupiedCoolingSetpoint::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeOccupiedCoolingSetpointWithValue:(NSNumber * _Nonnull)value
                                     completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeOccupiedCoolingSetpointWithValue:(NSNumber * _Nonnull) value
                                                  params:nil
                                       completionHandler:completionHandler];
}
- (void)writeAttributeOccupiedCoolingSetpointWithValue:(NSNumber * _Nonnull)value
                                                params:(MTRWriteParams * _Nullable)params
                                     completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = Thermostat::Attributes::OccupiedCoolingSetpoint::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.shortValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeOccupiedCoolingSetpointWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                     maxInterval:(NSNumber * _Nonnull)maxInterval
                                                          params:(MTRSubscribeParams * _Nullable)params
                                         subscriptionEstablished:
                                             (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                   reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Thermostat::Attributes::OccupiedCoolingSetpoint::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeOccupiedCoolingSetpointWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                             completionHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Thermostat::Attributes::OccupiedCoolingSetpoint::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeOccupiedHeatingSetpointWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Thermostat::Attributes::OccupiedHeatingSetpoint::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeOccupiedHeatingSetpointWithValue:(NSNumber * _Nonnull)value
                                     completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeOccupiedHeatingSetpointWithValue:(NSNumber * _Nonnull) value
                                                  params:nil
                                       completionHandler:completionHandler];
}
- (void)writeAttributeOccupiedHeatingSetpointWithValue:(NSNumber * _Nonnull)value
                                                params:(MTRWriteParams * _Nullable)params
                                     completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = Thermostat::Attributes::OccupiedHeatingSetpoint::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.shortValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeOccupiedHeatingSetpointWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                     maxInterval:(NSNumber * _Nonnull)maxInterval
                                                          params:(MTRSubscribeParams * _Nullable)params
                                         subscriptionEstablished:
                                             (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                   reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Thermostat::Attributes::OccupiedHeatingSetpoint::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeOccupiedHeatingSetpointWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                             completionHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Thermostat::Attributes::OccupiedHeatingSetpoint::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeUnoccupiedCoolingSetpointWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Thermostat::Attributes::UnoccupiedCoolingSetpoint::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeUnoccupiedCoolingSetpointWithValue:(NSNumber * _Nonnull)value
                                       completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeUnoccupiedCoolingSetpointWithValue:(NSNumber * _Nonnull) value
                                                    params:nil
                                         completionHandler:completionHandler];
}
- (void)writeAttributeUnoccupiedCoolingSetpointWithValue:(NSNumber * _Nonnull)value
                                                  params:(MTRWriteParams * _Nullable)params
                                       completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = Thermostat::Attributes::UnoccupiedCoolingSetpoint::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.shortValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeUnoccupiedCoolingSetpointWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                                            params:(MTRSubscribeParams * _Nullable)params
                                           subscriptionEstablished:
                                               (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                     reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Thermostat::Attributes::UnoccupiedCoolingSetpoint::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeUnoccupiedCoolingSetpointWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                        endpoint:(NSNumber *)endpoint
                                                           queue:(dispatch_queue_t)queue
                                               completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Thermostat::Attributes::UnoccupiedCoolingSetpoint::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeUnoccupiedHeatingSetpointWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Thermostat::Attributes::UnoccupiedHeatingSetpoint::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeUnoccupiedHeatingSetpointWithValue:(NSNumber * _Nonnull)value
                                       completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeUnoccupiedHeatingSetpointWithValue:(NSNumber * _Nonnull) value
                                                    params:nil
                                         completionHandler:completionHandler];
}
- (void)writeAttributeUnoccupiedHeatingSetpointWithValue:(NSNumber * _Nonnull)value
                                                  params:(MTRWriteParams * _Nullable)params
                                       completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = Thermostat::Attributes::UnoccupiedHeatingSetpoint::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.shortValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeUnoccupiedHeatingSetpointWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                                            params:(MTRSubscribeParams * _Nullable)params
                                           subscriptionEstablished:
                                               (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                     reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Thermostat::Attributes::UnoccupiedHeatingSetpoint::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeUnoccupiedHeatingSetpointWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                        endpoint:(NSNumber *)endpoint
                                                           queue:(dispatch_queue_t)queue
                                               completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Thermostat::Attributes::UnoccupiedHeatingSetpoint::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeMinHeatSetpointLimitWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Thermostat::Attributes::MinHeatSetpointLimit::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeMinHeatSetpointLimitWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeMinHeatSetpointLimitWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeMinHeatSetpointLimitWithValue:(NSNumber * _Nonnull)value
                                             params:(MTRWriteParams * _Nullable)params
                                  completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = Thermostat::Attributes::MinHeatSetpointLimit::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.shortValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeMinHeatSetpointLimitWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Thermostat::Attributes::MinHeatSetpointLimit::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeMinHeatSetpointLimitWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Thermostat::Attributes::MinHeatSetpointLimit::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeMaxHeatSetpointLimitWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Thermostat::Attributes::MaxHeatSetpointLimit::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeMaxHeatSetpointLimitWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeMaxHeatSetpointLimitWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeMaxHeatSetpointLimitWithValue:(NSNumber * _Nonnull)value
                                             params:(MTRWriteParams * _Nullable)params
                                  completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = Thermostat::Attributes::MaxHeatSetpointLimit::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.shortValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeMaxHeatSetpointLimitWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Thermostat::Attributes::MaxHeatSetpointLimit::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeMaxHeatSetpointLimitWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Thermostat::Attributes::MaxHeatSetpointLimit::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeMinCoolSetpointLimitWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Thermostat::Attributes::MinCoolSetpointLimit::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeMinCoolSetpointLimitWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeMinCoolSetpointLimitWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeMinCoolSetpointLimitWithValue:(NSNumber * _Nonnull)value
                                             params:(MTRWriteParams * _Nullable)params
                                  completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = Thermostat::Attributes::MinCoolSetpointLimit::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.shortValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeMinCoolSetpointLimitWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Thermostat::Attributes::MinCoolSetpointLimit::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeMinCoolSetpointLimitWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Thermostat::Attributes::MinCoolSetpointLimit::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeMaxCoolSetpointLimitWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Thermostat::Attributes::MaxCoolSetpointLimit::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeMaxCoolSetpointLimitWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeMaxCoolSetpointLimitWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeMaxCoolSetpointLimitWithValue:(NSNumber * _Nonnull)value
                                             params:(MTRWriteParams * _Nullable)params
                                  completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = Thermostat::Attributes::MaxCoolSetpointLimit::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.shortValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeMaxCoolSetpointLimitWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Thermostat::Attributes::MaxCoolSetpointLimit::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeMaxCoolSetpointLimitWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Thermostat::Attributes::MaxCoolSetpointLimit::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeMinSetpointDeadBandWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRInt8sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Thermostat::Attributes::MinSetpointDeadBand::TypeInfo;
            auto successFn = Callback<Int8sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeMinSetpointDeadBandWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeMinSetpointDeadBandWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeMinSetpointDeadBandWithValue:(NSNumber * _Nonnull)value
                                            params:(MTRWriteParams * _Nullable)params
                                 completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = Thermostat::Attributes::MinSetpointDeadBand::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.charValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeMinSetpointDeadBandWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Thermostat::Attributes::MinSetpointDeadBand::TypeInfo;
            auto successFn = Callback<Int8sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeMinSetpointDeadBandWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Thermostat::Attributes::MinSetpointDeadBand::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeRemoteSensingWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Thermostat::Attributes::RemoteSensing::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeRemoteSensingWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeRemoteSensingWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeRemoteSensingWithValue:(NSNumber * _Nonnull)value
                                      params:(MTRWriteParams * _Nullable)params
                           completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = Thermostat::Attributes::RemoteSensing::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedCharValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeRemoteSensingWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Thermostat::Attributes::RemoteSensing::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeRemoteSensingWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Thermostat::Attributes::RemoteSensing::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeControlSequenceOfOperationWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))completionHandler
{
    new MTRThermostatClusterThermostatControlSequenceAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Thermostat::Attributes::ControlSequenceOfOperation::TypeInfo;
            auto successFn = Callback<ThermostatClusterThermostatControlSequenceAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeControlSequenceOfOperationWithValue:(NSNumber * _Nonnull)value
                                        completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeControlSequenceOfOperationWithValue:(NSNumber * _Nonnull) value
                                                     params:nil
                                          completionHandler:completionHandler];
}
- (void)writeAttributeControlSequenceOfOperationWithValue:(NSNumber * _Nonnull)value
                                                   params:(MTRWriteParams * _Nullable)params
                                        completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = Thermostat::Attributes::ControlSequenceOfOperation::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = static_cast<std::remove_reference_t<decltype(cppValue)>>(value.unsignedCharValue);
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeControlSequenceOfOperationWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                                             params:(MTRSubscribeParams * _Nullable)params
                                            subscriptionEstablished:
                                                (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                      reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRThermostatClusterThermostatControlSequenceAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Thermostat::Attributes::ControlSequenceOfOperation::TypeInfo;
            auto successFn = Callback<ThermostatClusterThermostatControlSequenceAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRThermostatClusterThermostatControlSequenceAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeControlSequenceOfOperationWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                         endpoint:(NSNumber *)endpoint
                                                            queue:(dispatch_queue_t)queue
                                                completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))completionHandler
{
    new MTRThermostatClusterThermostatControlSequenceAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Thermostat::Attributes::ControlSequenceOfOperation::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<ThermostatClusterThermostatControlSequenceAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeSystemModeWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Thermostat::Attributes::SystemMode::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeSystemModeWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeSystemModeWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeSystemModeWithValue:(NSNumber * _Nonnull)value
                                   params:(MTRWriteParams * _Nullable)params
                        completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = Thermostat::Attributes::SystemMode::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedCharValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeSystemModeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Thermostat::Attributes::SystemMode::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeSystemModeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Thermostat::Attributes::SystemMode::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeThermostatRunningModeWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                    NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Thermostat::Attributes::ThermostatRunningMode::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeThermostatRunningModeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                   maxInterval:(NSNumber * _Nonnull)maxInterval
                                                        params:(MTRSubscribeParams * _Nullable)params
                                       subscriptionEstablished:
                                           (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                 reportHandler:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Thermostat::Attributes::ThermostatRunningMode::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeThermostatRunningModeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                           completionHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Thermostat::Attributes::ThermostatRunningMode::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeStartOfWeekWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Thermostat::Attributes::StartOfWeek::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeStartOfWeekWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Thermostat::Attributes::StartOfWeek::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeStartOfWeekWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Thermostat::Attributes::StartOfWeek::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeNumberOfWeeklyTransitionsWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Thermostat::Attributes::NumberOfWeeklyTransitions::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeNumberOfWeeklyTransitionsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                                            params:(MTRSubscribeParams * _Nullable)params
                                           subscriptionEstablished:
                                               (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                     reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Thermostat::Attributes::NumberOfWeeklyTransitions::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeNumberOfWeeklyTransitionsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                        endpoint:(NSNumber *)endpoint
                                                           queue:(dispatch_queue_t)queue
                                               completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Thermostat::Attributes::NumberOfWeeklyTransitions::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeNumberOfDailyTransitionsWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Thermostat::Attributes::NumberOfDailyTransitions::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeNumberOfDailyTransitionsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                                           params:(MTRSubscribeParams * _Nullable)params
                                          subscriptionEstablished:
                                              (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                    reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Thermostat::Attributes::NumberOfDailyTransitions::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeNumberOfDailyTransitionsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                       endpoint:(NSNumber *)endpoint
                                                          queue:(dispatch_queue_t)queue
                                              completionHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Thermostat::Attributes::NumberOfDailyTransitions::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeTemperatureSetpointHoldWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Thermostat::Attributes::TemperatureSetpointHold::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeTemperatureSetpointHoldWithValue:(NSNumber * _Nonnull)value
                                     completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeTemperatureSetpointHoldWithValue:(NSNumber * _Nonnull) value
                                                  params:nil
                                       completionHandler:completionHandler];
}
- (void)writeAttributeTemperatureSetpointHoldWithValue:(NSNumber * _Nonnull)value
                                                params:(MTRWriteParams * _Nullable)params
                                     completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = Thermostat::Attributes::TemperatureSetpointHold::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedCharValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeTemperatureSetpointHoldWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                     maxInterval:(NSNumber * _Nonnull)maxInterval
                                                          params:(MTRSubscribeParams * _Nullable)params
                                         subscriptionEstablished:
                                             (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                   reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Thermostat::Attributes::TemperatureSetpointHold::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeTemperatureSetpointHoldWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                             completionHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Thermostat::Attributes::TemperatureSetpointHold::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeTemperatureSetpointHoldDurationWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                              NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Thermostat::Attributes::TemperatureSetpointHoldDuration::TypeInfo;
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeTemperatureSetpointHoldDurationWithValue:(NSNumber * _Nullable)value
                                             completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeTemperatureSetpointHoldDurationWithValue:(NSNumber * _Nullable) value
                                                          params:nil
                                               completionHandler:completionHandler];
}
- (void)writeAttributeTemperatureSetpointHoldDurationWithValue:(NSNumber * _Nullable)value
                                                        params:(MTRWriteParams * _Nullable)params
                                             completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = Thermostat::Attributes::TemperatureSetpointHoldDuration::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.unsignedShortValue;
            }
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeTemperatureSetpointHoldDurationWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                  params:(MTRSubscribeParams * _Nullable)params
                                                 subscriptionEstablished:
                                                     (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                           reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                             NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Thermostat::Attributes::TemperatureSetpointHoldDuration::TypeInfo;
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeTemperatureSetpointHoldDurationWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                              endpoint:(NSNumber *)endpoint
                                                                 queue:(dispatch_queue_t)queue
                                                     completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Thermostat::Attributes::TemperatureSetpointHoldDuration::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeThermostatProgrammingOperationModeWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                                 NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Thermostat::Attributes::ThermostatProgrammingOperationMode::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeThermostatProgrammingOperationModeWithValue:(NSNumber * _Nonnull)value
                                                completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeThermostatProgrammingOperationModeWithValue:(NSNumber * _Nonnull) value
                                                             params:nil
                                                  completionHandler:completionHandler];
}
- (void)writeAttributeThermostatProgrammingOperationModeWithValue:(NSNumber * _Nonnull)value
                                                           params:(MTRWriteParams * _Nullable)params
                                                completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = Thermostat::Attributes::ThermostatProgrammingOperationMode::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedCharValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeThermostatProgrammingOperationModeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                                maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                     params:(MTRSubscribeParams * _Nullable)params
                                                    subscriptionEstablished:
                                                        (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                              reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                                NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Thermostat::Attributes::ThermostatProgrammingOperationMode::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeThermostatProgrammingOperationModeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                                 endpoint:(NSNumber *)endpoint
                                                                    queue:(dispatch_queue_t)queue
                                                        completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Thermostat::Attributes::ThermostatProgrammingOperationMode::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeThermostatRunningStateWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Thermostat::Attributes::ThermostatRunningState::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeThermostatRunningStateWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                                         params:(MTRSubscribeParams * _Nullable)params
                                        subscriptionEstablished:
                                            (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                  reportHandler:
                                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Thermostat::Attributes::ThermostatRunningState::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeThermostatRunningStateWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                            completionHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Thermostat::Attributes::ThermostatRunningState::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeSetpointChangeSourceWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Thermostat::Attributes::SetpointChangeSource::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeSetpointChangeSourceWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Thermostat::Attributes::SetpointChangeSource::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeSetpointChangeSourceWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Thermostat::Attributes::SetpointChangeSource::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeSetpointChangeAmountWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Thermostat::Attributes::SetpointChangeAmount::TypeInfo;
            auto successFn = Callback<NullableInt16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeSetpointChangeAmountWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Thermostat::Attributes::SetpointChangeAmount::TypeInfo;
            auto successFn = Callback<NullableInt16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeSetpointChangeAmountWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Thermostat::Attributes::SetpointChangeAmount::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeSetpointChangeSourceTimestampWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                            NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Thermostat::Attributes::SetpointChangeSourceTimestamp::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeSetpointChangeSourceTimestampWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                params:(MTRSubscribeParams * _Nullable)params
                                               subscriptionEstablished:
                                                   (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                         reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Thermostat::Attributes::SetpointChangeSourceTimestamp::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeSetpointChangeSourceTimestampWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                            endpoint:(NSNumber *)endpoint
                                                               queue:(dispatch_queue_t)queue
                                                   completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Thermostat::Attributes::SetpointChangeSourceTimestamp::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeOccupiedSetbackWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Thermostat::Attributes::OccupiedSetback::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeOccupiedSetbackWithValue:(NSNumber * _Nullable)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeOccupiedSetbackWithValue:(NSNumber * _Nullable) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeOccupiedSetbackWithValue:(NSNumber * _Nullable)value
                                        params:(MTRWriteParams * _Nullable)params
                             completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = Thermostat::Attributes::OccupiedSetback::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.unsignedCharValue;
            }
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeOccupiedSetbackWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Thermostat::Attributes::OccupiedSetback::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeOccupiedSetbackWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Thermostat::Attributes::OccupiedSetback::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeOccupiedSetbackMinWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                 NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Thermostat::Attributes::OccupiedSetbackMin::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeOccupiedSetbackMinWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                maxInterval:(NSNumber * _Nonnull)maxInterval
                                                     params:(MTRSubscribeParams * _Nullable)params
                                    subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                              reportHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Thermostat::Attributes::OccupiedSetbackMin::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeOccupiedSetbackMinWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                        completionHandler:
                                            (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Thermostat::Attributes::OccupiedSetbackMin::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeOccupiedSetbackMaxWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                 NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Thermostat::Attributes::OccupiedSetbackMax::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeOccupiedSetbackMaxWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                maxInterval:(NSNumber * _Nonnull)maxInterval
                                                     params:(MTRSubscribeParams * _Nullable)params
                                    subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                              reportHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Thermostat::Attributes::OccupiedSetbackMax::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeOccupiedSetbackMaxWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                        completionHandler:
                                            (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Thermostat::Attributes::OccupiedSetbackMax::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeUnoccupiedSetbackWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Thermostat::Attributes::UnoccupiedSetback::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeUnoccupiedSetbackWithValue:(NSNumber * _Nullable)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeUnoccupiedSetbackWithValue:(NSNumber * _Nullable) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeUnoccupiedSetbackWithValue:(NSNumber * _Nullable)value
                                          params:(MTRWriteParams * _Nullable)params
                               completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = Thermostat::Attributes::UnoccupiedSetback::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.unsignedCharValue;
            }
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeUnoccupiedSetbackWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Thermostat::Attributes::UnoccupiedSetback::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeUnoccupiedSetbackWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Thermostat::Attributes::UnoccupiedSetback::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeUnoccupiedSetbackMinWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Thermostat::Attributes::UnoccupiedSetbackMin::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeUnoccupiedSetbackMinWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Thermostat::Attributes::UnoccupiedSetbackMin::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeUnoccupiedSetbackMinWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Thermostat::Attributes::UnoccupiedSetbackMin::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeUnoccupiedSetbackMaxWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Thermostat::Attributes::UnoccupiedSetbackMax::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeUnoccupiedSetbackMaxWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Thermostat::Attributes::UnoccupiedSetbackMax::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeUnoccupiedSetbackMaxWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Thermostat::Attributes::UnoccupiedSetbackMax::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeEmergencyHeatDeltaWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                 NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Thermostat::Attributes::EmergencyHeatDelta::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeEmergencyHeatDeltaWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeEmergencyHeatDeltaWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeEmergencyHeatDeltaWithValue:(NSNumber * _Nonnull)value
                                           params:(MTRWriteParams * _Nullable)params
                                completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = Thermostat::Attributes::EmergencyHeatDelta::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedCharValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeEmergencyHeatDeltaWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                maxInterval:(NSNumber * _Nonnull)maxInterval
                                                     params:(MTRSubscribeParams * _Nullable)params
                                    subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                              reportHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Thermostat::Attributes::EmergencyHeatDelta::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeEmergencyHeatDeltaWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                        completionHandler:
                                            (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Thermostat::Attributes::EmergencyHeatDelta::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeACTypeWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Thermostat::Attributes::ACType::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeACTypeWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeACTypeWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeACTypeWithValue:(NSNumber * _Nonnull)value
                               params:(MTRWriteParams * _Nullable)params
                    completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = Thermostat::Attributes::ACType::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedCharValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeACTypeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                         params:(MTRSubscribeParams * _Nullable)params
                        subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Thermostat::Attributes::ACType::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeACTypeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                     endpoint:(NSNumber *)endpoint
                                        queue:(dispatch_queue_t)queue
                            completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Thermostat::Attributes::ACType::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeACCapacityWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Thermostat::Attributes::ACCapacity::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeACCapacityWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeACCapacityWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeACCapacityWithValue:(NSNumber * _Nonnull)value
                                   params:(MTRWriteParams * _Nullable)params
                        completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = Thermostat::Attributes::ACCapacity::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeACCapacityWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Thermostat::Attributes::ACCapacity::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeACCapacityWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Thermostat::Attributes::ACCapacity::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeACRefrigerantTypeWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Thermostat::Attributes::ACRefrigerantType::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeACRefrigerantTypeWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeACRefrigerantTypeWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeACRefrigerantTypeWithValue:(NSNumber * _Nonnull)value
                                          params:(MTRWriteParams * _Nullable)params
                               completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = Thermostat::Attributes::ACRefrigerantType::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedCharValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeACRefrigerantTypeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Thermostat::Attributes::ACRefrigerantType::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeACRefrigerantTypeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Thermostat::Attributes::ACRefrigerantType::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeACCompressorTypeWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Thermostat::Attributes::ACCompressorType::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeACCompressorTypeWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeACCompressorTypeWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeACCompressorTypeWithValue:(NSNumber * _Nonnull)value
                                         params:(MTRWriteParams * _Nullable)params
                              completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = Thermostat::Attributes::ACCompressorType::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedCharValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeACCompressorTypeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                              maxInterval:(NSNumber * _Nonnull)maxInterval
                                                   params:(MTRSubscribeParams * _Nullable)params
                                  subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                            reportHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Thermostat::Attributes::ACCompressorType::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeACCompressorTypeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Thermostat::Attributes::ACCompressorType::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeACErrorCodeWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Thermostat::Attributes::ACErrorCode::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeACErrorCodeWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeACErrorCodeWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeACErrorCodeWithValue:(NSNumber * _Nonnull)value
                                    params:(MTRWriteParams * _Nullable)params
                         completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = Thermostat::Attributes::ACErrorCode::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedIntValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeACErrorCodeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Thermostat::Attributes::ACErrorCode::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeACErrorCodeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Thermostat::Attributes::ACErrorCode::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeACLouverPositionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Thermostat::Attributes::ACLouverPosition::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeACLouverPositionWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeACLouverPositionWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeACLouverPositionWithValue:(NSNumber * _Nonnull)value
                                         params:(MTRWriteParams * _Nullable)params
                              completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = Thermostat::Attributes::ACLouverPosition::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedCharValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeACLouverPositionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                              maxInterval:(NSNumber * _Nonnull)maxInterval
                                                   params:(MTRSubscribeParams * _Nullable)params
                                  subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                            reportHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Thermostat::Attributes::ACLouverPosition::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeACLouverPositionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Thermostat::Attributes::ACLouverPosition::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeACCoilTemperatureWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Thermostat::Attributes::ACCoilTemperature::TypeInfo;
            auto successFn = Callback<NullableInt16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeACCoilTemperatureWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Thermostat::Attributes::ACCoilTemperature::TypeInfo;
            auto successFn = Callback<NullableInt16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeACCoilTemperatureWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Thermostat::Attributes::ACCoilTemperature::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeACCapacityformatWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Thermostat::Attributes::ACCapacityformat::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeACCapacityformatWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeACCapacityformatWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeACCapacityformatWithValue:(NSNumber * _Nonnull)value
                                         params:(MTRWriteParams * _Nullable)params
                              completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = Thermostat::Attributes::ACCapacityformat::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedCharValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeACCapacityformatWithMinInterval:(NSNumber * _Nonnull)minInterval
                                              maxInterval:(NSNumber * _Nonnull)maxInterval
                                                   params:(MTRSubscribeParams * _Nullable)params
                                  subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                            reportHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Thermostat::Attributes::ACCapacityformat::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeACCapacityformatWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Thermostat::Attributes::ACCapacityformat::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRThermostatGeneratedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Thermostat::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<ThermostatGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRThermostatGeneratedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Thermostat::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<ThermostatGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRThermostatGeneratedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRThermostatGeneratedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Thermostat::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<ThermostatGeneratedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRThermostatAcceptedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Thermostat::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<ThermostatAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRThermostatAcceptedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Thermostat::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<ThermostatAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRThermostatAcceptedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRThermostatAcceptedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Thermostat::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<ThermostatAcceptedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRThermostatAttributeListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Thermostat::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<ThermostatAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRThermostatAttributeListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Thermostat::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<ThermostatAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRThermostatAttributeListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRThermostatAttributeListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Thermostat::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<ThermostatAttributeListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Thermostat::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Thermostat::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Thermostat::Attributes::FeatureMap::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Thermostat::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Thermostat::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Thermostat::Attributes::ClusterRevision::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

@end

@implementation MTRBaseClusterFanControl

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = endpoint;
    }
    return self;
}

- (void)readAttributeFanModeWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRFanControlClusterFanModeTypeAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = FanControl::Attributes::FanMode::TypeInfo;
            auto successFn = Callback<FanControlClusterFanModeTypeAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::FanControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeFanModeWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeFanModeWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeFanModeWithValue:(NSNumber * _Nonnull)value
                                params:(MTRWriteParams * _Nullable)params
                     completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = FanControl::Attributes::FanMode::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = static_cast<std::remove_reference_t<decltype(cppValue)>>(value.unsignedCharValue);
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::FanControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeFanModeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                     maxInterval:(NSNumber * _Nonnull)maxInterval
                                          params:(MTRSubscribeParams * _Nullable)params
                         subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                   reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRFanControlClusterFanModeTypeAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = FanControl::Attributes::FanMode::TypeInfo;
            auto successFn = Callback<FanControlClusterFanModeTypeAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::FanControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRFanControlClusterFanModeTypeAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeFanModeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                      endpoint:(NSNumber *)endpoint
                                         queue:(dispatch_queue_t)queue
                             completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRFanControlClusterFanModeTypeAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = FanControl::Attributes::FanMode::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<FanControlClusterFanModeTypeAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFanModeSequenceWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRFanControlClusterFanModeSequenceTypeAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = FanControl::Attributes::FanModeSequence::TypeInfo;
            auto successFn = Callback<FanControlClusterFanModeSequenceTypeAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::FanControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeFanModeSequenceWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeFanModeSequenceWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeFanModeSequenceWithValue:(NSNumber * _Nonnull)value
                                        params:(MTRWriteParams * _Nullable)params
                             completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = FanControl::Attributes::FanModeSequence::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = static_cast<std::remove_reference_t<decltype(cppValue)>>(value.unsignedCharValue);
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::FanControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeFanModeSequenceWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRFanControlClusterFanModeSequenceTypeAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = FanControl::Attributes::FanModeSequence::TypeInfo;
            auto successFn = Callback<FanControlClusterFanModeSequenceTypeAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::FanControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRFanControlClusterFanModeSequenceTypeAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeFanModeSequenceWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRFanControlClusterFanModeSequenceTypeAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = FanControl::Attributes::FanModeSequence::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<FanControlClusterFanModeSequenceTypeAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributePercentSettingWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = FanControl::Attributes::PercentSetting::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::FanControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributePercentSettingWithValue:(NSNumber * _Nullable)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributePercentSettingWithValue:(NSNumber * _Nullable) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributePercentSettingWithValue:(NSNumber * _Nullable)value
                                       params:(MTRWriteParams * _Nullable)params
                            completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = FanControl::Attributes::PercentSetting::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.unsignedCharValue;
            }
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::FanControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributePercentSettingWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = FanControl::Attributes::PercentSetting::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::FanControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributePercentSettingWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = FanControl::Attributes::PercentSetting::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributePercentCurrentWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = FanControl::Attributes::PercentCurrent::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::FanControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributePercentCurrentWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = FanControl::Attributes::PercentCurrent::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::FanControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributePercentCurrentWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = FanControl::Attributes::PercentCurrent::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeSpeedMaxWithCompletionHandler:(void (^)(
                                                       NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = FanControl::Attributes::SpeedMax::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::FanControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeSpeedMaxWithMinInterval:(NSNumber * _Nonnull)minInterval
                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                           params:(MTRSubscribeParams * _Nullable)params
                          subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = FanControl::Attributes::SpeedMax::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::FanControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeSpeedMaxWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                       endpoint:(NSNumber *)endpoint
                                          queue:(dispatch_queue_t)queue
                              completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = FanControl::Attributes::SpeedMax::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeSpeedSettingWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = FanControl::Attributes::SpeedSetting::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::FanControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeSpeedSettingWithValue:(NSNumber * _Nullable)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeSpeedSettingWithValue:(NSNumber * _Nullable) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeSpeedSettingWithValue:(NSNumber * _Nullable)value
                                     params:(MTRWriteParams * _Nullable)params
                          completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = FanControl::Attributes::SpeedSetting::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.unsignedCharValue;
            }
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::FanControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeSpeedSettingWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = FanControl::Attributes::SpeedSetting::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::FanControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeSpeedSettingWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = FanControl::Attributes::SpeedSetting::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeSpeedCurrentWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = FanControl::Attributes::SpeedCurrent::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::FanControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeSpeedCurrentWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = FanControl::Attributes::SpeedCurrent::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::FanControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeSpeedCurrentWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = FanControl::Attributes::SpeedCurrent::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeRockSupportWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = FanControl::Attributes::RockSupport::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::FanControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeRockSupportWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = FanControl::Attributes::RockSupport::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::FanControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeRockSupportWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = FanControl::Attributes::RockSupport::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeRockSettingWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = FanControl::Attributes::RockSetting::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::FanControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeRockSettingWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeRockSettingWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeRockSettingWithValue:(NSNumber * _Nonnull)value
                                    params:(MTRWriteParams * _Nullable)params
                         completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = FanControl::Attributes::RockSetting::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedCharValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::FanControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeRockSettingWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = FanControl::Attributes::RockSetting::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::FanControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeRockSettingWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = FanControl::Attributes::RockSetting::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeWindSupportWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = FanControl::Attributes::WindSupport::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::FanControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeWindSupportWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = FanControl::Attributes::WindSupport::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::FanControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeWindSupportWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = FanControl::Attributes::WindSupport::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeWindSettingWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = FanControl::Attributes::WindSetting::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::FanControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeWindSettingWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeWindSettingWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeWindSettingWithValue:(NSNumber * _Nonnull)value
                                    params:(MTRWriteParams * _Nullable)params
                         completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = FanControl::Attributes::WindSetting::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedCharValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::FanControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeWindSettingWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = FanControl::Attributes::WindSetting::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::FanControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeWindSettingWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = FanControl::Attributes::WindSetting::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRFanControlGeneratedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = FanControl::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<FanControlGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::FanControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRFanControlGeneratedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = FanControl::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<FanControlGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::FanControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRFanControlGeneratedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRFanControlGeneratedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = FanControl::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<FanControlGeneratedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRFanControlAcceptedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = FanControl::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<FanControlAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::FanControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRFanControlAcceptedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = FanControl::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<FanControlAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::FanControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRFanControlAcceptedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRFanControlAcceptedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = FanControl::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<FanControlAcceptedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRFanControlAttributeListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = FanControl::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<FanControlAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::FanControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRFanControlAttributeListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = FanControl::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<FanControlAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::FanControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRFanControlAttributeListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRFanControlAttributeListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = FanControl::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<FanControlAttributeListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = FanControl::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::FanControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = FanControl::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::FanControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = FanControl::Attributes::FeatureMap::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = FanControl::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::FanControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = FanControl::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::FanControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = FanControl::Attributes::ClusterRevision::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

@end

@implementation MTRBaseClusterThermostatUserInterfaceConfiguration

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = endpoint;
    }
    return self;
}

- (void)readAttributeTemperatureDisplayModeWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThermostatUserInterfaceConfiguration::Attributes::TemperatureDisplayMode::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThermostatUserInterfaceConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeTemperatureDisplayModeWithValue:(NSNumber * _Nonnull)value
                                    completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeTemperatureDisplayModeWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeTemperatureDisplayModeWithValue:(NSNumber * _Nonnull)value
                                               params:(MTRWriteParams * _Nullable)params
                                    completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = ThermostatUserInterfaceConfiguration::Attributes::TemperatureDisplayMode::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedCharValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatUserInterfaceConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeTemperatureDisplayModeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                                         params:(MTRSubscribeParams * _Nullable)params
                                        subscriptionEstablished:
                                            (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                  reportHandler:
                                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThermostatUserInterfaceConfiguration::Attributes::TemperatureDisplayMode::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatUserInterfaceConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeTemperatureDisplayModeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                            completionHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ThermostatUserInterfaceConfiguration::Attributes::TemperatureDisplayMode::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeKeypadLockoutWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThermostatUserInterfaceConfiguration::Attributes::KeypadLockout::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThermostatUserInterfaceConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeKeypadLockoutWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeKeypadLockoutWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeKeypadLockoutWithValue:(NSNumber * _Nonnull)value
                                      params:(MTRWriteParams * _Nullable)params
                           completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = ThermostatUserInterfaceConfiguration::Attributes::KeypadLockout::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedCharValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatUserInterfaceConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeKeypadLockoutWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThermostatUserInterfaceConfiguration::Attributes::KeypadLockout::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatUserInterfaceConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeKeypadLockoutWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ThermostatUserInterfaceConfiguration::Attributes::KeypadLockout::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeScheduleProgrammingVisibilityWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                            NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThermostatUserInterfaceConfiguration::Attributes::ScheduleProgrammingVisibility::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThermostatUserInterfaceConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeScheduleProgrammingVisibilityWithValue:(NSNumber * _Nonnull)value
                                           completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeScheduleProgrammingVisibilityWithValue:(NSNumber * _Nonnull) value
                                                        params:nil
                                             completionHandler:completionHandler];
}
- (void)writeAttributeScheduleProgrammingVisibilityWithValue:(NSNumber * _Nonnull)value
                                                      params:(MTRWriteParams * _Nullable)params
                                           completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = ThermostatUserInterfaceConfiguration::Attributes::ScheduleProgrammingVisibility::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedCharValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatUserInterfaceConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeScheduleProgrammingVisibilityWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                params:(MTRSubscribeParams * _Nullable)params
                                               subscriptionEstablished:
                                                   (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                         reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThermostatUserInterfaceConfiguration::Attributes::ScheduleProgrammingVisibility::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatUserInterfaceConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeScheduleProgrammingVisibilityWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                            endpoint:(NSNumber *)endpoint
                                                               queue:(dispatch_queue_t)queue
                                                   completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ThermostatUserInterfaceConfiguration::Attributes::ScheduleProgrammingVisibility::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRThermostatUserInterfaceConfigurationGeneratedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device,
        completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThermostatUserInterfaceConfiguration::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn
                = Callback<ThermostatUserInterfaceConfigurationGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThermostatUserInterfaceConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRThermostatUserInterfaceConfigurationGeneratedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThermostatUserInterfaceConfiguration::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn
                = Callback<ThermostatUserInterfaceConfigurationGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatUserInterfaceConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRThermostatUserInterfaceConfigurationGeneratedCommandListListAttributeCallbackSubscriptionBridge::
                    OnSubscriptionEstablished,
                nil, params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRThermostatUserInterfaceConfigurationGeneratedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThermostatUserInterfaceConfiguration::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn
                    = Callback<ThermostatUserInterfaceConfigurationGeneratedCommandListListAttributeCallback>::FromCancelable(
                        success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRThermostatUserInterfaceConfigurationAcceptedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device,
        completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThermostatUserInterfaceConfiguration::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn
                = Callback<ThermostatUserInterfaceConfigurationAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThermostatUserInterfaceConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRThermostatUserInterfaceConfigurationAcceptedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThermostatUserInterfaceConfiguration::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn
                = Callback<ThermostatUserInterfaceConfigurationAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatUserInterfaceConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRThermostatUserInterfaceConfigurationAcceptedCommandListListAttributeCallbackSubscriptionBridge::
                    OnSubscriptionEstablished,
                nil, params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRThermostatUserInterfaceConfigurationAcceptedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThermostatUserInterfaceConfiguration::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn
                    = Callback<ThermostatUserInterfaceConfigurationAcceptedCommandListListAttributeCallback>::FromCancelable(
                        success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRThermostatUserInterfaceConfigurationAttributeListListAttributeCallbackBridge(self.callbackQueue, self.device,
        completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThermostatUserInterfaceConfiguration::Attributes::AttributeList::TypeInfo;
            auto successFn
                = Callback<ThermostatUserInterfaceConfigurationAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThermostatUserInterfaceConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRThermostatUserInterfaceConfigurationAttributeListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThermostatUserInterfaceConfiguration::Attributes::AttributeList::TypeInfo;
            auto successFn
                = Callback<ThermostatUserInterfaceConfigurationAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatUserInterfaceConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRThermostatUserInterfaceConfigurationAttributeListListAttributeCallbackSubscriptionBridge::
                    OnSubscriptionEstablished,
                nil, params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRThermostatUserInterfaceConfigurationAttributeListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ThermostatUserInterfaceConfiguration::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn
                    = Callback<ThermostatUserInterfaceConfigurationAttributeListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThermostatUserInterfaceConfiguration::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThermostatUserInterfaceConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThermostatUserInterfaceConfiguration::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatUserInterfaceConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ThermostatUserInterfaceConfiguration::Attributes::FeatureMap::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ThermostatUserInterfaceConfiguration::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ThermostatUserInterfaceConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ThermostatUserInterfaceConfiguration::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ThermostatUserInterfaceConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ThermostatUserInterfaceConfiguration::Attributes::ClusterRevision::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

@end

@implementation MTRBaseClusterColorControl

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = endpoint;
    }
    return self;
}

- (void)moveToHueWithParams:(MTRColorControlClusterMoveToHueParams *)params completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            ColorControl::Commands::MoveToHue::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.hue = params.hue.unsignedCharValue;
            request.direction
                = static_cast<std::remove_reference_t<decltype(request.direction)>>(params.direction.unsignedCharValue);
            request.transitionTime = params.transitionTime.unsignedShortValue;
            request.optionsMask = params.optionsMask.unsignedCharValue;
            request.optionsOverride = params.optionsOverride.unsignedCharValue;

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)moveHueWithParams:(MTRColorControlClusterMoveHueParams *)params completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            ColorControl::Commands::MoveHue::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.moveMode = static_cast<std::remove_reference_t<decltype(request.moveMode)>>(params.moveMode.unsignedCharValue);
            request.rate = params.rate.unsignedCharValue;
            request.optionsMask = params.optionsMask.unsignedCharValue;
            request.optionsOverride = params.optionsOverride.unsignedCharValue;

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)stepHueWithParams:(MTRColorControlClusterStepHueParams *)params completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            ColorControl::Commands::StepHue::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.stepMode = static_cast<std::remove_reference_t<decltype(request.stepMode)>>(params.stepMode.unsignedCharValue);
            request.stepSize = params.stepSize.unsignedCharValue;
            request.transitionTime = params.transitionTime.unsignedCharValue;
            request.optionsMask = params.optionsMask.unsignedCharValue;
            request.optionsOverride = params.optionsOverride.unsignedCharValue;

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)moveToSaturationWithParams:(MTRColorControlClusterMoveToSaturationParams *)params
                 completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            ColorControl::Commands::MoveToSaturation::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.saturation = params.saturation.unsignedCharValue;
            request.transitionTime = params.transitionTime.unsignedShortValue;
            request.optionsMask = params.optionsMask.unsignedCharValue;
            request.optionsOverride = params.optionsOverride.unsignedCharValue;

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)moveSaturationWithParams:(MTRColorControlClusterMoveSaturationParams *)params
               completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            ColorControl::Commands::MoveSaturation::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.moveMode = static_cast<std::remove_reference_t<decltype(request.moveMode)>>(params.moveMode.unsignedCharValue);
            request.rate = params.rate.unsignedCharValue;
            request.optionsMask = params.optionsMask.unsignedCharValue;
            request.optionsOverride = params.optionsOverride.unsignedCharValue;

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)stepSaturationWithParams:(MTRColorControlClusterStepSaturationParams *)params
               completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            ColorControl::Commands::StepSaturation::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.stepMode = static_cast<std::remove_reference_t<decltype(request.stepMode)>>(params.stepMode.unsignedCharValue);
            request.stepSize = params.stepSize.unsignedCharValue;
            request.transitionTime = params.transitionTime.unsignedCharValue;
            request.optionsMask = params.optionsMask.unsignedCharValue;
            request.optionsOverride = params.optionsOverride.unsignedCharValue;

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)moveToHueAndSaturationWithParams:(MTRColorControlClusterMoveToHueAndSaturationParams *)params
                       completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            ColorControl::Commands::MoveToHueAndSaturation::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.hue = params.hue.unsignedCharValue;
            request.saturation = params.saturation.unsignedCharValue;
            request.transitionTime = params.transitionTime.unsignedShortValue;
            request.optionsMask = params.optionsMask.unsignedCharValue;
            request.optionsOverride = params.optionsOverride.unsignedCharValue;

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)moveToColorWithParams:(MTRColorControlClusterMoveToColorParams *)params
            completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            ColorControl::Commands::MoveToColor::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.colorX = params.colorX.unsignedShortValue;
            request.colorY = params.colorY.unsignedShortValue;
            request.transitionTime = params.transitionTime.unsignedShortValue;
            request.optionsMask = params.optionsMask.unsignedCharValue;
            request.optionsOverride = params.optionsOverride.unsignedCharValue;

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)moveColorWithParams:(MTRColorControlClusterMoveColorParams *)params completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            ColorControl::Commands::MoveColor::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.rateX = params.rateX.shortValue;
            request.rateY = params.rateY.shortValue;
            request.optionsMask = params.optionsMask.unsignedCharValue;
            request.optionsOverride = params.optionsOverride.unsignedCharValue;

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)stepColorWithParams:(MTRColorControlClusterStepColorParams *)params completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            ColorControl::Commands::StepColor::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.stepX = params.stepX.shortValue;
            request.stepY = params.stepY.shortValue;
            request.transitionTime = params.transitionTime.unsignedShortValue;
            request.optionsMask = params.optionsMask.unsignedCharValue;
            request.optionsOverride = params.optionsOverride.unsignedCharValue;

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)moveToColorTemperatureWithParams:(MTRColorControlClusterMoveToColorTemperatureParams *)params
                       completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            ColorControl::Commands::MoveToColorTemperature::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.colorTemperature = params.colorTemperature.unsignedShortValue;
            request.transitionTime = params.transitionTime.unsignedShortValue;
            request.optionsMask = params.optionsMask.unsignedCharValue;
            request.optionsOverride = params.optionsOverride.unsignedCharValue;

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)enhancedMoveToHueWithParams:(MTRColorControlClusterEnhancedMoveToHueParams *)params
                  completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            ColorControl::Commands::EnhancedMoveToHue::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.enhancedHue = params.enhancedHue.unsignedShortValue;
            request.direction
                = static_cast<std::remove_reference_t<decltype(request.direction)>>(params.direction.unsignedCharValue);
            request.transitionTime = params.transitionTime.unsignedShortValue;
            request.optionsMask = params.optionsMask.unsignedCharValue;
            request.optionsOverride = params.optionsOverride.unsignedCharValue;

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)enhancedMoveHueWithParams:(MTRColorControlClusterEnhancedMoveHueParams *)params
                completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            ColorControl::Commands::EnhancedMoveHue::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.moveMode = static_cast<std::remove_reference_t<decltype(request.moveMode)>>(params.moveMode.unsignedCharValue);
            request.rate = params.rate.unsignedShortValue;
            request.optionsMask = params.optionsMask.unsignedCharValue;
            request.optionsOverride = params.optionsOverride.unsignedCharValue;

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)enhancedStepHueWithParams:(MTRColorControlClusterEnhancedStepHueParams *)params
                completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            ColorControl::Commands::EnhancedStepHue::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.stepMode = static_cast<std::remove_reference_t<decltype(request.stepMode)>>(params.stepMode.unsignedCharValue);
            request.stepSize = params.stepSize.unsignedShortValue;
            request.transitionTime = params.transitionTime.unsignedShortValue;
            request.optionsMask = params.optionsMask.unsignedCharValue;
            request.optionsOverride = params.optionsOverride.unsignedCharValue;

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)enhancedMoveToHueAndSaturationWithParams:(MTRColorControlClusterEnhancedMoveToHueAndSaturationParams *)params
                               completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            ColorControl::Commands::EnhancedMoveToHueAndSaturation::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.enhancedHue = params.enhancedHue.unsignedShortValue;
            request.saturation = params.saturation.unsignedCharValue;
            request.transitionTime = params.transitionTime.unsignedShortValue;
            request.optionsMask = params.optionsMask.unsignedCharValue;
            request.optionsOverride = params.optionsOverride.unsignedCharValue;

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)colorLoopSetWithParams:(MTRColorControlClusterColorLoopSetParams *)params
             completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            ColorControl::Commands::ColorLoopSet::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.updateFlags
                = static_cast<std::remove_reference_t<decltype(request.updateFlags)>>(params.updateFlags.unsignedCharValue);
            request.action = static_cast<std::remove_reference_t<decltype(request.action)>>(params.action.unsignedCharValue);
            request.direction
                = static_cast<std::remove_reference_t<decltype(request.direction)>>(params.direction.unsignedCharValue);
            request.time = params.time.unsignedShortValue;
            request.startHue = params.startHue.unsignedShortValue;
            request.optionsMask = params.optionsMask.unsignedCharValue;
            request.optionsOverride = params.optionsOverride.unsignedCharValue;

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)stopMoveStepWithParams:(MTRColorControlClusterStopMoveStepParams *)params
             completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            ColorControl::Commands::StopMoveStep::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.optionsMask = params.optionsMask.unsignedCharValue;
            request.optionsOverride = params.optionsOverride.unsignedCharValue;

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)moveColorTemperatureWithParams:(MTRColorControlClusterMoveColorTemperatureParams *)params
                     completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            ColorControl::Commands::MoveColorTemperature::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.moveMode = static_cast<std::remove_reference_t<decltype(request.moveMode)>>(params.moveMode.unsignedCharValue);
            request.rate = params.rate.unsignedShortValue;
            request.colorTemperatureMinimumMireds = params.colorTemperatureMinimumMireds.unsignedShortValue;
            request.colorTemperatureMaximumMireds = params.colorTemperatureMaximumMireds.unsignedShortValue;
            request.optionsMask = params.optionsMask.unsignedCharValue;
            request.optionsOverride = params.optionsOverride.unsignedCharValue;

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)stepColorTemperatureWithParams:(MTRColorControlClusterStepColorTemperatureParams *)params
                     completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            ColorControl::Commands::StepColorTemperature::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.stepMode = static_cast<std::remove_reference_t<decltype(request.stepMode)>>(params.stepMode.unsignedCharValue);
            request.stepSize = params.stepSize.unsignedShortValue;
            request.transitionTime = params.transitionTime.unsignedShortValue;
            request.colorTemperatureMinimumMireds = params.colorTemperatureMinimumMireds.unsignedShortValue;
            request.colorTemperatureMaximumMireds = params.colorTemperatureMaximumMireds.unsignedShortValue;
            request.optionsMask = params.optionsMask.unsignedCharValue;
            request.optionsOverride = params.optionsOverride.unsignedCharValue;

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)readAttributeCurrentHueWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ColorControl::Attributes::CurrentHue::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeCurrentHueWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ColorControl::Attributes::CurrentHue::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeCurrentHueWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ColorControl::Attributes::CurrentHue::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeCurrentSaturationWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ColorControl::Attributes::CurrentSaturation::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeCurrentSaturationWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ColorControl::Attributes::CurrentSaturation::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeCurrentSaturationWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ColorControl::Attributes::CurrentSaturation::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeRemainingTimeWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ColorControl::Attributes::RemainingTime::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeRemainingTimeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ColorControl::Attributes::RemainingTime::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeRemainingTimeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ColorControl::Attributes::RemainingTime::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeCurrentXWithCompletionHandler:(void (^)(
                                                       NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ColorControl::Attributes::CurrentX::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeCurrentXWithMinInterval:(NSNumber * _Nonnull)minInterval
                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                           params:(MTRSubscribeParams * _Nullable)params
                          subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ColorControl::Attributes::CurrentX::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeCurrentXWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                       endpoint:(NSNumber *)endpoint
                                          queue:(dispatch_queue_t)queue
                              completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ColorControl::Attributes::CurrentX::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeCurrentYWithCompletionHandler:(void (^)(
                                                       NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ColorControl::Attributes::CurrentY::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeCurrentYWithMinInterval:(NSNumber * _Nonnull)minInterval
                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                           params:(MTRSubscribeParams * _Nullable)params
                          subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ColorControl::Attributes::CurrentY::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeCurrentYWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                       endpoint:(NSNumber *)endpoint
                                          queue:(dispatch_queue_t)queue
                              completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ColorControl::Attributes::CurrentY::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeDriftCompensationWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ColorControl::Attributes::DriftCompensation::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeDriftCompensationWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ColorControl::Attributes::DriftCompensation::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeDriftCompensationWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ColorControl::Attributes::DriftCompensation::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeCompensationTextWithCompletionHandler:(void (^)(NSString * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ColorControl::Attributes::CompensationText::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeCompensationTextWithMinInterval:(NSNumber * _Nonnull)minInterval
                                              maxInterval:(NSNumber * _Nonnull)maxInterval
                                                   params:(MTRSubscribeParams * _Nullable)params
                                  subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                            reportHandler:
                                                (void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRCharStringAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ColorControl::Attributes::CompensationText::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRCharStringAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeCompensationTextWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ColorControl::Attributes::CompensationText::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeColorTemperatureWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ColorControl::Attributes::ColorTemperature::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeColorTemperatureWithMinInterval:(NSNumber * _Nonnull)minInterval
                                              maxInterval:(NSNumber * _Nonnull)maxInterval
                                                   params:(MTRSubscribeParams * _Nullable)params
                                  subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                            reportHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ColorControl::Attributes::ColorTemperature::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeColorTemperatureWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ColorControl::Attributes::ColorTemperature::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeColorModeWithCompletionHandler:(void (^)(
                                                        NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ColorControl::Attributes::ColorMode::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeColorModeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ColorControl::Attributes::ColorMode::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeColorModeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ColorControl::Attributes::ColorMode::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeOptionsWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ColorControl::Attributes::Options::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeOptionsWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeOptionsWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeOptionsWithValue:(NSNumber * _Nonnull)value
                                params:(MTRWriteParams * _Nullable)params
                     completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = ColorControl::Attributes::Options::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedCharValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeOptionsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                     maxInterval:(NSNumber * _Nonnull)maxInterval
                                          params:(MTRSubscribeParams * _Nullable)params
                         subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                   reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ColorControl::Attributes::Options::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeOptionsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                      endpoint:(NSNumber *)endpoint
                                         queue:(dispatch_queue_t)queue
                             completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ColorControl::Attributes::Options::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeNumberOfPrimariesWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ColorControl::Attributes::NumberOfPrimaries::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeNumberOfPrimariesWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ColorControl::Attributes::NumberOfPrimaries::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeNumberOfPrimariesWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ColorControl::Attributes::NumberOfPrimaries::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributePrimary1XWithCompletionHandler:(void (^)(
                                                        NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ColorControl::Attributes::Primary1X::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributePrimary1XWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ColorControl::Attributes::Primary1X::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributePrimary1XWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ColorControl::Attributes::Primary1X::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributePrimary1YWithCompletionHandler:(void (^)(
                                                        NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ColorControl::Attributes::Primary1Y::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributePrimary1YWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ColorControl::Attributes::Primary1Y::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributePrimary1YWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ColorControl::Attributes::Primary1Y::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributePrimary1IntensityWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ColorControl::Attributes::Primary1Intensity::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributePrimary1IntensityWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ColorControl::Attributes::Primary1Intensity::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributePrimary1IntensityWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ColorControl::Attributes::Primary1Intensity::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributePrimary2XWithCompletionHandler:(void (^)(
                                                        NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ColorControl::Attributes::Primary2X::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributePrimary2XWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ColorControl::Attributes::Primary2X::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributePrimary2XWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ColorControl::Attributes::Primary2X::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributePrimary2YWithCompletionHandler:(void (^)(
                                                        NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ColorControl::Attributes::Primary2Y::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributePrimary2YWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ColorControl::Attributes::Primary2Y::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributePrimary2YWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ColorControl::Attributes::Primary2Y::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributePrimary2IntensityWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ColorControl::Attributes::Primary2Intensity::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributePrimary2IntensityWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ColorControl::Attributes::Primary2Intensity::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributePrimary2IntensityWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ColorControl::Attributes::Primary2Intensity::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributePrimary3XWithCompletionHandler:(void (^)(
                                                        NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ColorControl::Attributes::Primary3X::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributePrimary3XWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ColorControl::Attributes::Primary3X::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributePrimary3XWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ColorControl::Attributes::Primary3X::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributePrimary3YWithCompletionHandler:(void (^)(
                                                        NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ColorControl::Attributes::Primary3Y::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributePrimary3YWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ColorControl::Attributes::Primary3Y::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributePrimary3YWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ColorControl::Attributes::Primary3Y::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributePrimary3IntensityWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ColorControl::Attributes::Primary3Intensity::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributePrimary3IntensityWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ColorControl::Attributes::Primary3Intensity::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributePrimary3IntensityWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ColorControl::Attributes::Primary3Intensity::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributePrimary4XWithCompletionHandler:(void (^)(
                                                        NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ColorControl::Attributes::Primary4X::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributePrimary4XWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ColorControl::Attributes::Primary4X::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributePrimary4XWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ColorControl::Attributes::Primary4X::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributePrimary4YWithCompletionHandler:(void (^)(
                                                        NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ColorControl::Attributes::Primary4Y::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributePrimary4YWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ColorControl::Attributes::Primary4Y::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributePrimary4YWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ColorControl::Attributes::Primary4Y::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributePrimary4IntensityWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ColorControl::Attributes::Primary4Intensity::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributePrimary4IntensityWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ColorControl::Attributes::Primary4Intensity::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributePrimary4IntensityWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ColorControl::Attributes::Primary4Intensity::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributePrimary5XWithCompletionHandler:(void (^)(
                                                        NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ColorControl::Attributes::Primary5X::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributePrimary5XWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ColorControl::Attributes::Primary5X::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributePrimary5XWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ColorControl::Attributes::Primary5X::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributePrimary5YWithCompletionHandler:(void (^)(
                                                        NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ColorControl::Attributes::Primary5Y::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributePrimary5YWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ColorControl::Attributes::Primary5Y::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributePrimary5YWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ColorControl::Attributes::Primary5Y::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributePrimary5IntensityWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ColorControl::Attributes::Primary5Intensity::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributePrimary5IntensityWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ColorControl::Attributes::Primary5Intensity::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributePrimary5IntensityWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ColorControl::Attributes::Primary5Intensity::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributePrimary6XWithCompletionHandler:(void (^)(
                                                        NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ColorControl::Attributes::Primary6X::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributePrimary6XWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ColorControl::Attributes::Primary6X::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributePrimary6XWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ColorControl::Attributes::Primary6X::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributePrimary6YWithCompletionHandler:(void (^)(
                                                        NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ColorControl::Attributes::Primary6Y::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributePrimary6YWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ColorControl::Attributes::Primary6Y::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributePrimary6YWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ColorControl::Attributes::Primary6Y::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributePrimary6IntensityWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ColorControl::Attributes::Primary6Intensity::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributePrimary6IntensityWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ColorControl::Attributes::Primary6Intensity::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributePrimary6IntensityWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ColorControl::Attributes::Primary6Intensity::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeWhitePointXWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ColorControl::Attributes::WhitePointX::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeWhitePointXWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeWhitePointXWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeWhitePointXWithValue:(NSNumber * _Nonnull)value
                                    params:(MTRWriteParams * _Nullable)params
                         completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = ColorControl::Attributes::WhitePointX::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeWhitePointXWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ColorControl::Attributes::WhitePointX::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeWhitePointXWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ColorControl::Attributes::WhitePointX::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeWhitePointYWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ColorControl::Attributes::WhitePointY::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeWhitePointYWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeWhitePointYWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeWhitePointYWithValue:(NSNumber * _Nonnull)value
                                    params:(MTRWriteParams * _Nullable)params
                         completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = ColorControl::Attributes::WhitePointY::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeWhitePointYWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ColorControl::Attributes::WhitePointY::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeWhitePointYWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ColorControl::Attributes::WhitePointY::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeColorPointRXWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ColorControl::Attributes::ColorPointRX::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeColorPointRXWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeColorPointRXWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeColorPointRXWithValue:(NSNumber * _Nonnull)value
                                     params:(MTRWriteParams * _Nullable)params
                          completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = ColorControl::Attributes::ColorPointRX::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeColorPointRXWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ColorControl::Attributes::ColorPointRX::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeColorPointRXWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ColorControl::Attributes::ColorPointRX::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeColorPointRYWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ColorControl::Attributes::ColorPointRY::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeColorPointRYWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeColorPointRYWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeColorPointRYWithValue:(NSNumber * _Nonnull)value
                                     params:(MTRWriteParams * _Nullable)params
                          completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = ColorControl::Attributes::ColorPointRY::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeColorPointRYWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ColorControl::Attributes::ColorPointRY::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeColorPointRYWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ColorControl::Attributes::ColorPointRY::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeColorPointRIntensityWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ColorControl::Attributes::ColorPointRIntensity::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeColorPointRIntensityWithValue:(NSNumber * _Nullable)value
                                  completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeColorPointRIntensityWithValue:(NSNumber * _Nullable) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeColorPointRIntensityWithValue:(NSNumber * _Nullable)value
                                             params:(MTRWriteParams * _Nullable)params
                                  completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = ColorControl::Attributes::ColorPointRIntensity::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.unsignedCharValue;
            }
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeColorPointRIntensityWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ColorControl::Attributes::ColorPointRIntensity::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeColorPointRIntensityWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ColorControl::Attributes::ColorPointRIntensity::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeColorPointGXWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ColorControl::Attributes::ColorPointGX::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeColorPointGXWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeColorPointGXWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeColorPointGXWithValue:(NSNumber * _Nonnull)value
                                     params:(MTRWriteParams * _Nullable)params
                          completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = ColorControl::Attributes::ColorPointGX::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeColorPointGXWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ColorControl::Attributes::ColorPointGX::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeColorPointGXWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ColorControl::Attributes::ColorPointGX::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeColorPointGYWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ColorControl::Attributes::ColorPointGY::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeColorPointGYWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeColorPointGYWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeColorPointGYWithValue:(NSNumber * _Nonnull)value
                                     params:(MTRWriteParams * _Nullable)params
                          completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = ColorControl::Attributes::ColorPointGY::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeColorPointGYWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ColorControl::Attributes::ColorPointGY::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeColorPointGYWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ColorControl::Attributes::ColorPointGY::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeColorPointGIntensityWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ColorControl::Attributes::ColorPointGIntensity::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeColorPointGIntensityWithValue:(NSNumber * _Nullable)value
                                  completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeColorPointGIntensityWithValue:(NSNumber * _Nullable) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeColorPointGIntensityWithValue:(NSNumber * _Nullable)value
                                             params:(MTRWriteParams * _Nullable)params
                                  completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = ColorControl::Attributes::ColorPointGIntensity::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.unsignedCharValue;
            }
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeColorPointGIntensityWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ColorControl::Attributes::ColorPointGIntensity::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeColorPointGIntensityWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ColorControl::Attributes::ColorPointGIntensity::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeColorPointBXWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ColorControl::Attributes::ColorPointBX::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeColorPointBXWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeColorPointBXWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeColorPointBXWithValue:(NSNumber * _Nonnull)value
                                     params:(MTRWriteParams * _Nullable)params
                          completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = ColorControl::Attributes::ColorPointBX::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeColorPointBXWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ColorControl::Attributes::ColorPointBX::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeColorPointBXWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ColorControl::Attributes::ColorPointBX::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeColorPointBYWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ColorControl::Attributes::ColorPointBY::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeColorPointBYWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeColorPointBYWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeColorPointBYWithValue:(NSNumber * _Nonnull)value
                                     params:(MTRWriteParams * _Nullable)params
                          completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = ColorControl::Attributes::ColorPointBY::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeColorPointBYWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ColorControl::Attributes::ColorPointBY::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeColorPointBYWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ColorControl::Attributes::ColorPointBY::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeColorPointBIntensityWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ColorControl::Attributes::ColorPointBIntensity::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeColorPointBIntensityWithValue:(NSNumber * _Nullable)value
                                  completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeColorPointBIntensityWithValue:(NSNumber * _Nullable) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeColorPointBIntensityWithValue:(NSNumber * _Nullable)value
                                             params:(MTRWriteParams * _Nullable)params
                                  completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = ColorControl::Attributes::ColorPointBIntensity::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.unsignedCharValue;
            }
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeColorPointBIntensityWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ColorControl::Attributes::ColorPointBIntensity::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeColorPointBIntensityWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ColorControl::Attributes::ColorPointBIntensity::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeEnhancedCurrentHueWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                 NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ColorControl::Attributes::EnhancedCurrentHue::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeEnhancedCurrentHueWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                maxInterval:(NSNumber * _Nonnull)maxInterval
                                                     params:(MTRSubscribeParams * _Nullable)params
                                    subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                              reportHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ColorControl::Attributes::EnhancedCurrentHue::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeEnhancedCurrentHueWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                        completionHandler:
                                            (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ColorControl::Attributes::EnhancedCurrentHue::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeEnhancedColorModeWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ColorControl::Attributes::EnhancedColorMode::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeEnhancedColorModeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ColorControl::Attributes::EnhancedColorMode::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeEnhancedColorModeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ColorControl::Attributes::EnhancedColorMode::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeColorLoopActiveWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ColorControl::Attributes::ColorLoopActive::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeColorLoopActiveWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ColorControl::Attributes::ColorLoopActive::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeColorLoopActiveWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ColorControl::Attributes::ColorLoopActive::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeColorLoopDirectionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                 NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ColorControl::Attributes::ColorLoopDirection::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeColorLoopDirectionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                maxInterval:(NSNumber * _Nonnull)maxInterval
                                                     params:(MTRSubscribeParams * _Nullable)params
                                    subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                              reportHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ColorControl::Attributes::ColorLoopDirection::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeColorLoopDirectionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                        completionHandler:
                                            (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ColorControl::Attributes::ColorLoopDirection::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeColorLoopTimeWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ColorControl::Attributes::ColorLoopTime::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeColorLoopTimeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ColorControl::Attributes::ColorLoopTime::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeColorLoopTimeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ColorControl::Attributes::ColorLoopTime::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeColorLoopStartEnhancedHueWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ColorControl::Attributes::ColorLoopStartEnhancedHue::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeColorLoopStartEnhancedHueWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                                            params:(MTRSubscribeParams * _Nullable)params
                                           subscriptionEstablished:
                                               (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                     reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ColorControl::Attributes::ColorLoopStartEnhancedHue::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeColorLoopStartEnhancedHueWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                        endpoint:(NSNumber *)endpoint
                                                           queue:(dispatch_queue_t)queue
                                               completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ColorControl::Attributes::ColorLoopStartEnhancedHue::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeColorLoopStoredEnhancedHueWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ColorControl::Attributes::ColorLoopStoredEnhancedHue::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeColorLoopStoredEnhancedHueWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                                             params:(MTRSubscribeParams * _Nullable)params
                                            subscriptionEstablished:
                                                (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                      reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ColorControl::Attributes::ColorLoopStoredEnhancedHue::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeColorLoopStoredEnhancedHueWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                         endpoint:(NSNumber *)endpoint
                                                            queue:(dispatch_queue_t)queue
                                                completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ColorControl::Attributes::ColorLoopStoredEnhancedHue::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeColorCapabilitiesWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ColorControl::Attributes::ColorCapabilities::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeColorCapabilitiesWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ColorControl::Attributes::ColorCapabilities::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeColorCapabilitiesWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ColorControl::Attributes::ColorCapabilities::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeColorTempPhysicalMinMiredsWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ColorControl::Attributes::ColorTempPhysicalMinMireds::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeColorTempPhysicalMinMiredsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                                             params:(MTRSubscribeParams * _Nullable)params
                                            subscriptionEstablished:
                                                (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                      reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ColorControl::Attributes::ColorTempPhysicalMinMireds::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeColorTempPhysicalMinMiredsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                         endpoint:(NSNumber *)endpoint
                                                            queue:(dispatch_queue_t)queue
                                                completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ColorControl::Attributes::ColorTempPhysicalMinMireds::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeColorTempPhysicalMaxMiredsWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ColorControl::Attributes::ColorTempPhysicalMaxMireds::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeColorTempPhysicalMaxMiredsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                                             params:(MTRSubscribeParams * _Nullable)params
                                            subscriptionEstablished:
                                                (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                      reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ColorControl::Attributes::ColorTempPhysicalMaxMireds::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeColorTempPhysicalMaxMiredsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                         endpoint:(NSNumber *)endpoint
                                                            queue:(dispatch_queue_t)queue
                                                completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ColorControl::Attributes::ColorTempPhysicalMaxMireds::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeCoupleColorTempToLevelMinMiredsWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ColorControl::Attributes::CoupleColorTempToLevelMinMireds::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeCoupleColorTempToLevelMinMiredsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                  params:(MTRSubscribeParams * _Nullable)params
                                                 subscriptionEstablished:
                                                     (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                           reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                             NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ColorControl::Attributes::CoupleColorTempToLevelMinMireds::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeCoupleColorTempToLevelMinMiredsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                              endpoint:(NSNumber *)endpoint
                                                                 queue:(dispatch_queue_t)queue
                                                     completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ColorControl::Attributes::CoupleColorTempToLevelMinMireds::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeStartUpColorTemperatureMiredsWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                            NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ColorControl::Attributes::StartUpColorTemperatureMireds::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeStartUpColorTemperatureMiredsWithValue:(NSNumber * _Nonnull)value
                                           completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeStartUpColorTemperatureMiredsWithValue:(NSNumber * _Nonnull) value
                                                        params:nil
                                             completionHandler:completionHandler];
}
- (void)writeAttributeStartUpColorTemperatureMiredsWithValue:(NSNumber * _Nonnull)value
                                                      params:(MTRWriteParams * _Nullable)params
                                           completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = ColorControl::Attributes::StartUpColorTemperatureMireds::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeStartUpColorTemperatureMiredsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                params:(MTRSubscribeParams * _Nullable)params
                                               subscriptionEstablished:
                                                   (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                         reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ColorControl::Attributes::StartUpColorTemperatureMireds::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeStartUpColorTemperatureMiredsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                            endpoint:(NSNumber *)endpoint
                                                               queue:(dispatch_queue_t)queue
                                                   completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ColorControl::Attributes::StartUpColorTemperatureMireds::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRColorControlGeneratedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ColorControl::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<ColorControlGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRColorControlGeneratedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ColorControl::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<ColorControlGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRColorControlGeneratedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRColorControlGeneratedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ColorControl::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<ColorControlGeneratedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRColorControlAcceptedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ColorControl::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<ColorControlAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRColorControlAcceptedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ColorControl::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<ColorControlAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRColorControlAcceptedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRColorControlAcceptedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ColorControl::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<ColorControlAcceptedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRColorControlAttributeListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ColorControl::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<ColorControlAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRColorControlAttributeListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ColorControl::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<ColorControlAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRColorControlAttributeListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRColorControlAttributeListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ColorControl::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<ColorControlAttributeListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ColorControl::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ColorControl::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ColorControl::Attributes::FeatureMap::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ColorControl::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ColorControl::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ColorControlCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ColorControl::Attributes::ClusterRevision::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

@end

@implementation MTRBaseClusterBallastConfiguration

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = endpoint;
    }
    return self;
}

- (void)readAttributePhysicalMinLevelWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BallastConfiguration::Attributes::PhysicalMinLevel::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BallastConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributePhysicalMinLevelWithMinInterval:(NSNumber * _Nonnull)minInterval
                                              maxInterval:(NSNumber * _Nonnull)maxInterval
                                                   params:(MTRSubscribeParams * _Nullable)params
                                  subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                            reportHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BallastConfiguration::Attributes::PhysicalMinLevel::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BallastConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributePhysicalMinLevelWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = BallastConfiguration::Attributes::PhysicalMinLevel::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributePhysicalMaxLevelWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BallastConfiguration::Attributes::PhysicalMaxLevel::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BallastConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributePhysicalMaxLevelWithMinInterval:(NSNumber * _Nonnull)minInterval
                                              maxInterval:(NSNumber * _Nonnull)maxInterval
                                                   params:(MTRSubscribeParams * _Nullable)params
                                  subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                            reportHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BallastConfiguration::Attributes::PhysicalMaxLevel::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BallastConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributePhysicalMaxLevelWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = BallastConfiguration::Attributes::PhysicalMaxLevel::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeBallastStatusWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BallastConfiguration::Attributes::BallastStatus::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BallastConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeBallastStatusWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BallastConfiguration::Attributes::BallastStatus::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BallastConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeBallastStatusWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = BallastConfiguration::Attributes::BallastStatus::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeMinLevelWithCompletionHandler:(void (^)(
                                                       NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BallastConfiguration::Attributes::MinLevel::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BallastConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeMinLevelWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeMinLevelWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeMinLevelWithValue:(NSNumber * _Nonnull)value
                                 params:(MTRWriteParams * _Nullable)params
                      completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = BallastConfiguration::Attributes::MinLevel::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedCharValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BallastConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeMinLevelWithMinInterval:(NSNumber * _Nonnull)minInterval
                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                           params:(MTRSubscribeParams * _Nullable)params
                          subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BallastConfiguration::Attributes::MinLevel::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BallastConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeMinLevelWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                       endpoint:(NSNumber *)endpoint
                                          queue:(dispatch_queue_t)queue
                              completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = BallastConfiguration::Attributes::MinLevel::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeMaxLevelWithCompletionHandler:(void (^)(
                                                       NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BallastConfiguration::Attributes::MaxLevel::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BallastConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeMaxLevelWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeMaxLevelWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeMaxLevelWithValue:(NSNumber * _Nonnull)value
                                 params:(MTRWriteParams * _Nullable)params
                      completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = BallastConfiguration::Attributes::MaxLevel::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedCharValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BallastConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeMaxLevelWithMinInterval:(NSNumber * _Nonnull)minInterval
                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                           params:(MTRSubscribeParams * _Nullable)params
                          subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BallastConfiguration::Attributes::MaxLevel::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BallastConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeMaxLevelWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                       endpoint:(NSNumber *)endpoint
                                          queue:(dispatch_queue_t)queue
                              completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = BallastConfiguration::Attributes::MaxLevel::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeIntrinsicBalanceFactorWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BallastConfiguration::Attributes::IntrinsicBalanceFactor::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BallastConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeIntrinsicBalanceFactorWithValue:(NSNumber * _Nullable)value
                                    completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeIntrinsicBalanceFactorWithValue:(NSNumber * _Nullable) value
                                                 params:nil
                                      completionHandler:completionHandler];
}
- (void)writeAttributeIntrinsicBalanceFactorWithValue:(NSNumber * _Nullable)value
                                               params:(MTRWriteParams * _Nullable)params
                                    completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = BallastConfiguration::Attributes::IntrinsicBalanceFactor::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.unsignedCharValue;
            }
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BallastConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeIntrinsicBalanceFactorWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                                         params:(MTRSubscribeParams * _Nullable)params
                                        subscriptionEstablished:
                                            (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                  reportHandler:
                                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BallastConfiguration::Attributes::IntrinsicBalanceFactor::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BallastConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeIntrinsicBalanceFactorWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                            completionHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = BallastConfiguration::Attributes::IntrinsicBalanceFactor::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeBallastFactorAdjustmentWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BallastConfiguration::Attributes::BallastFactorAdjustment::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BallastConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeBallastFactorAdjustmentWithValue:(NSNumber * _Nullable)value
                                     completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeBallastFactorAdjustmentWithValue:(NSNumber * _Nullable) value
                                                  params:nil
                                       completionHandler:completionHandler];
}
- (void)writeAttributeBallastFactorAdjustmentWithValue:(NSNumber * _Nullable)value
                                                params:(MTRWriteParams * _Nullable)params
                                     completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = BallastConfiguration::Attributes::BallastFactorAdjustment::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.unsignedCharValue;
            }
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BallastConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeBallastFactorAdjustmentWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                     maxInterval:(NSNumber * _Nonnull)maxInterval
                                                          params:(MTRSubscribeParams * _Nullable)params
                                         subscriptionEstablished:
                                             (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                   reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BallastConfiguration::Attributes::BallastFactorAdjustment::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BallastConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeBallastFactorAdjustmentWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                             completionHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = BallastConfiguration::Attributes::BallastFactorAdjustment::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeLampQuantityWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BallastConfiguration::Attributes::LampQuantity::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BallastConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeLampQuantityWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BallastConfiguration::Attributes::LampQuantity::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BallastConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeLampQuantityWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = BallastConfiguration::Attributes::LampQuantity::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeLampTypeWithCompletionHandler:(void (^)(
                                                       NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BallastConfiguration::Attributes::LampType::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BallastConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeLampTypeWithValue:(NSString * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeLampTypeWithValue:(NSString * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeLampTypeWithValue:(NSString * _Nonnull)value
                                 params:(MTRWriteParams * _Nullable)params
                      completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = BallastConfiguration::Attributes::LampType::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = [self asCharSpan:value];
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BallastConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeLampTypeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                           params:(MTRSubscribeParams * _Nullable)params
                          subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                    reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRCharStringAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BallastConfiguration::Attributes::LampType::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BallastConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRCharStringAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeLampTypeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                       endpoint:(NSNumber *)endpoint
                                          queue:(dispatch_queue_t)queue
                              completionHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = BallastConfiguration::Attributes::LampType::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeLampManufacturerWithCompletionHandler:(void (^)(NSString * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BallastConfiguration::Attributes::LampManufacturer::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BallastConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeLampManufacturerWithValue:(NSString * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeLampManufacturerWithValue:(NSString * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeLampManufacturerWithValue:(NSString * _Nonnull)value
                                         params:(MTRWriteParams * _Nullable)params
                              completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = BallastConfiguration::Attributes::LampManufacturer::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = [self asCharSpan:value];
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BallastConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeLampManufacturerWithMinInterval:(NSNumber * _Nonnull)minInterval
                                              maxInterval:(NSNumber * _Nonnull)maxInterval
                                                   params:(MTRSubscribeParams * _Nullable)params
                                  subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                            reportHandler:
                                                (void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRCharStringAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BallastConfiguration::Attributes::LampManufacturer::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BallastConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRCharStringAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeLampManufacturerWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = BallastConfiguration::Attributes::LampManufacturer::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeLampRatedHoursWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    new MTRNullableInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BallastConfiguration::Attributes::LampRatedHours::TypeInfo;
            auto successFn = Callback<NullableInt32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BallastConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeLampRatedHoursWithValue:(NSNumber * _Nullable)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeLampRatedHoursWithValue:(NSNumber * _Nullable) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeLampRatedHoursWithValue:(NSNumber * _Nullable)value
                                       params:(MTRWriteParams * _Nullable)params
                            completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = BallastConfiguration::Attributes::LampRatedHours::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.unsignedIntValue;
            }
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BallastConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeLampRatedHoursWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BallastConfiguration::Attributes::LampRatedHours::TypeInfo;
            auto successFn = Callback<NullableInt32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BallastConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeLampRatedHoursWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = BallastConfiguration::Attributes::LampRatedHours::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeLampBurnHoursWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BallastConfiguration::Attributes::LampBurnHours::TypeInfo;
            auto successFn = Callback<NullableInt32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BallastConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeLampBurnHoursWithValue:(NSNumber * _Nullable)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeLampBurnHoursWithValue:(NSNumber * _Nullable) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeLampBurnHoursWithValue:(NSNumber * _Nullable)value
                                      params:(MTRWriteParams * _Nullable)params
                           completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = BallastConfiguration::Attributes::LampBurnHours::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.unsignedIntValue;
            }
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BallastConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeLampBurnHoursWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BallastConfiguration::Attributes::LampBurnHours::TypeInfo;
            auto successFn = Callback<NullableInt32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BallastConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeLampBurnHoursWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = BallastConfiguration::Attributes::LampBurnHours::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeLampAlarmModeWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BallastConfiguration::Attributes::LampAlarmMode::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BallastConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeLampAlarmModeWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeLampAlarmModeWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeLampAlarmModeWithValue:(NSNumber * _Nonnull)value
                                      params:(MTRWriteParams * _Nullable)params
                           completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = BallastConfiguration::Attributes::LampAlarmMode::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedCharValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BallastConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeLampAlarmModeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BallastConfiguration::Attributes::LampAlarmMode::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BallastConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeLampAlarmModeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = BallastConfiguration::Attributes::LampAlarmMode::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeLampBurnHoursTripPointWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completionHandler
{
    new MTRNullableInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BallastConfiguration::Attributes::LampBurnHoursTripPoint::TypeInfo;
            auto successFn = Callback<NullableInt32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BallastConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeLampBurnHoursTripPointWithValue:(NSNumber * _Nullable)value
                                    completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeLampBurnHoursTripPointWithValue:(NSNumber * _Nullable) value
                                                 params:nil
                                      completionHandler:completionHandler];
}
- (void)writeAttributeLampBurnHoursTripPointWithValue:(NSNumber * _Nullable)value
                                               params:(MTRWriteParams * _Nullable)params
                                    completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = BallastConfiguration::Attributes::LampBurnHoursTripPoint::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.unsignedIntValue;
            }
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BallastConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeLampBurnHoursTripPointWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                                         params:(MTRSubscribeParams * _Nullable)params
                                        subscriptionEstablished:
                                            (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                  reportHandler:
                                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BallastConfiguration::Attributes::LampBurnHoursTripPoint::TypeInfo;
            auto successFn = Callback<NullableInt32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BallastConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeLampBurnHoursTripPointWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                            completionHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = BallastConfiguration::Attributes::LampBurnHoursTripPoint::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRBallastConfigurationGeneratedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BallastConfiguration::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<BallastConfigurationGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BallastConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRBallastConfigurationGeneratedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BallastConfiguration::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<BallastConfigurationGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BallastConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRBallastConfigurationGeneratedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBallastConfigurationGeneratedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BallastConfiguration::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<BallastConfigurationGeneratedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRBallastConfigurationAcceptedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BallastConfiguration::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<BallastConfigurationAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BallastConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRBallastConfigurationAcceptedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BallastConfiguration::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<BallastConfigurationAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BallastConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRBallastConfigurationAcceptedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBallastConfigurationAcceptedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BallastConfiguration::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<BallastConfigurationAcceptedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBallastConfigurationAttributeListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BallastConfiguration::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<BallastConfigurationAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BallastConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRBallastConfigurationAttributeListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BallastConfiguration::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<BallastConfigurationAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BallastConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRBallastConfigurationAttributeListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBallastConfigurationAttributeListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = BallastConfiguration::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<BallastConfigurationAttributeListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BallastConfiguration::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BallastConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BallastConfiguration::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BallastConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = BallastConfiguration::Attributes::FeatureMap::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = BallastConfiguration::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::BallastConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = BallastConfiguration::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::BallastConfigurationCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = BallastConfiguration::Attributes::ClusterRevision::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

@end

@implementation MTRBaseClusterIlluminanceMeasurement

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = endpoint;
    }
    return self;
}

- (void)readAttributeMeasuredValueWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = IlluminanceMeasurement::Attributes::MeasuredValue::TypeInfo;
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::IlluminanceMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeMeasuredValueWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = IlluminanceMeasurement::Attributes::MeasuredValue::TypeInfo;
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::IlluminanceMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeMeasuredValueWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = IlluminanceMeasurement::Attributes::MeasuredValue::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeMinMeasuredValueWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = IlluminanceMeasurement::Attributes::MinMeasuredValue::TypeInfo;
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::IlluminanceMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeMinMeasuredValueWithMinInterval:(NSNumber * _Nonnull)minInterval
                                              maxInterval:(NSNumber * _Nonnull)maxInterval
                                                   params:(MTRSubscribeParams * _Nullable)params
                                  subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                            reportHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = IlluminanceMeasurement::Attributes::MinMeasuredValue::TypeInfo;
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::IlluminanceMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeMinMeasuredValueWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = IlluminanceMeasurement::Attributes::MinMeasuredValue::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeMaxMeasuredValueWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = IlluminanceMeasurement::Attributes::MaxMeasuredValue::TypeInfo;
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::IlluminanceMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeMaxMeasuredValueWithMinInterval:(NSNumber * _Nonnull)minInterval
                                              maxInterval:(NSNumber * _Nonnull)maxInterval
                                                   params:(MTRSubscribeParams * _Nullable)params
                                  subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                            reportHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = IlluminanceMeasurement::Attributes::MaxMeasuredValue::TypeInfo;
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::IlluminanceMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeMaxMeasuredValueWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = IlluminanceMeasurement::Attributes::MaxMeasuredValue::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeToleranceWithCompletionHandler:(void (^)(
                                                        NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = IlluminanceMeasurement::Attributes::Tolerance::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::IlluminanceMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeToleranceWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = IlluminanceMeasurement::Attributes::Tolerance::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::IlluminanceMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeToleranceWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = IlluminanceMeasurement::Attributes::Tolerance::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeLightSensorTypeWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = IlluminanceMeasurement::Attributes::LightSensorType::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::IlluminanceMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeLightSensorTypeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = IlluminanceMeasurement::Attributes::LightSensorType::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::IlluminanceMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeLightSensorTypeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = IlluminanceMeasurement::Attributes::LightSensorType::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRIlluminanceMeasurementGeneratedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = IlluminanceMeasurement::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<IlluminanceMeasurementGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::IlluminanceMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRIlluminanceMeasurementGeneratedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = IlluminanceMeasurement::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<IlluminanceMeasurementGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::IlluminanceMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRIlluminanceMeasurementGeneratedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished,
                nil, params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRIlluminanceMeasurementGeneratedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = IlluminanceMeasurement::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<IlluminanceMeasurementGeneratedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRIlluminanceMeasurementAcceptedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = IlluminanceMeasurement::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<IlluminanceMeasurementAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::IlluminanceMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRIlluminanceMeasurementAcceptedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = IlluminanceMeasurement::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<IlluminanceMeasurementAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::IlluminanceMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRIlluminanceMeasurementAcceptedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRIlluminanceMeasurementAcceptedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = IlluminanceMeasurement::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<IlluminanceMeasurementAcceptedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRIlluminanceMeasurementAttributeListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = IlluminanceMeasurement::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<IlluminanceMeasurementAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::IlluminanceMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRIlluminanceMeasurementAttributeListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = IlluminanceMeasurement::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<IlluminanceMeasurementAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::IlluminanceMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRIlluminanceMeasurementAttributeListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRIlluminanceMeasurementAttributeListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = IlluminanceMeasurement::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<IlluminanceMeasurementAttributeListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = IlluminanceMeasurement::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::IlluminanceMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = IlluminanceMeasurement::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::IlluminanceMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = IlluminanceMeasurement::Attributes::FeatureMap::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = IlluminanceMeasurement::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::IlluminanceMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = IlluminanceMeasurement::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::IlluminanceMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = IlluminanceMeasurement::Attributes::ClusterRevision::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

@end

@implementation MTRBaseClusterTemperatureMeasurement

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = endpoint;
    }
    return self;
}

- (void)readAttributeMeasuredValueWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TemperatureMeasurement::Attributes::MeasuredValue::TypeInfo;
            auto successFn = Callback<NullableInt16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TemperatureMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeMeasuredValueWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TemperatureMeasurement::Attributes::MeasuredValue::TypeInfo;
            auto successFn = Callback<NullableInt16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TemperatureMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeMeasuredValueWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TemperatureMeasurement::Attributes::MeasuredValue::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeMinMeasuredValueWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TemperatureMeasurement::Attributes::MinMeasuredValue::TypeInfo;
            auto successFn = Callback<NullableInt16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TemperatureMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeMinMeasuredValueWithMinInterval:(NSNumber * _Nonnull)minInterval
                                              maxInterval:(NSNumber * _Nonnull)maxInterval
                                                   params:(MTRSubscribeParams * _Nullable)params
                                  subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                            reportHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TemperatureMeasurement::Attributes::MinMeasuredValue::TypeInfo;
            auto successFn = Callback<NullableInt16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TemperatureMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeMinMeasuredValueWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TemperatureMeasurement::Attributes::MinMeasuredValue::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeMaxMeasuredValueWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TemperatureMeasurement::Attributes::MaxMeasuredValue::TypeInfo;
            auto successFn = Callback<NullableInt16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TemperatureMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeMaxMeasuredValueWithMinInterval:(NSNumber * _Nonnull)minInterval
                                              maxInterval:(NSNumber * _Nonnull)maxInterval
                                                   params:(MTRSubscribeParams * _Nullable)params
                                  subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                            reportHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TemperatureMeasurement::Attributes::MaxMeasuredValue::TypeInfo;
            auto successFn = Callback<NullableInt16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TemperatureMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeMaxMeasuredValueWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TemperatureMeasurement::Attributes::MaxMeasuredValue::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeToleranceWithCompletionHandler:(void (^)(
                                                        NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TemperatureMeasurement::Attributes::Tolerance::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TemperatureMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeToleranceWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TemperatureMeasurement::Attributes::Tolerance::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TemperatureMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeToleranceWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TemperatureMeasurement::Attributes::Tolerance::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRTemperatureMeasurementGeneratedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TemperatureMeasurement::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<TemperatureMeasurementGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TemperatureMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRTemperatureMeasurementGeneratedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TemperatureMeasurement::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<TemperatureMeasurementGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TemperatureMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRTemperatureMeasurementGeneratedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished,
                nil, params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRTemperatureMeasurementGeneratedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TemperatureMeasurement::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<TemperatureMeasurementGeneratedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRTemperatureMeasurementAcceptedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TemperatureMeasurement::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<TemperatureMeasurementAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TemperatureMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRTemperatureMeasurementAcceptedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TemperatureMeasurement::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<TemperatureMeasurementAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TemperatureMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRTemperatureMeasurementAcceptedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRTemperatureMeasurementAcceptedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TemperatureMeasurement::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<TemperatureMeasurementAcceptedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRTemperatureMeasurementAttributeListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TemperatureMeasurement::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<TemperatureMeasurementAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TemperatureMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRTemperatureMeasurementAttributeListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TemperatureMeasurement::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<TemperatureMeasurementAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TemperatureMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRTemperatureMeasurementAttributeListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRTemperatureMeasurementAttributeListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TemperatureMeasurement::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<TemperatureMeasurementAttributeListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TemperatureMeasurement::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TemperatureMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TemperatureMeasurement::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TemperatureMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TemperatureMeasurement::Attributes::FeatureMap::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TemperatureMeasurement::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TemperatureMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TemperatureMeasurement::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TemperatureMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TemperatureMeasurement::Attributes::ClusterRevision::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

@end

@implementation MTRBaseClusterPressureMeasurement

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = endpoint;
    }
    return self;
}

- (void)readAttributeMeasuredValueWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PressureMeasurement::Attributes::MeasuredValue::TypeInfo;
            auto successFn = Callback<NullableInt16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PressureMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeMeasuredValueWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PressureMeasurement::Attributes::MeasuredValue::TypeInfo;
            auto successFn = Callback<NullableInt16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PressureMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeMeasuredValueWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = PressureMeasurement::Attributes::MeasuredValue::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeMinMeasuredValueWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PressureMeasurement::Attributes::MinMeasuredValue::TypeInfo;
            auto successFn = Callback<NullableInt16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PressureMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeMinMeasuredValueWithMinInterval:(NSNumber * _Nonnull)minInterval
                                              maxInterval:(NSNumber * _Nonnull)maxInterval
                                                   params:(MTRSubscribeParams * _Nullable)params
                                  subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                            reportHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PressureMeasurement::Attributes::MinMeasuredValue::TypeInfo;
            auto successFn = Callback<NullableInt16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PressureMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeMinMeasuredValueWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = PressureMeasurement::Attributes::MinMeasuredValue::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeMaxMeasuredValueWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PressureMeasurement::Attributes::MaxMeasuredValue::TypeInfo;
            auto successFn = Callback<NullableInt16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PressureMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeMaxMeasuredValueWithMinInterval:(NSNumber * _Nonnull)minInterval
                                              maxInterval:(NSNumber * _Nonnull)maxInterval
                                                   params:(MTRSubscribeParams * _Nullable)params
                                  subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                            reportHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PressureMeasurement::Attributes::MaxMeasuredValue::TypeInfo;
            auto successFn = Callback<NullableInt16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PressureMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeMaxMeasuredValueWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = PressureMeasurement::Attributes::MaxMeasuredValue::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeToleranceWithCompletionHandler:(void (^)(
                                                        NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PressureMeasurement::Attributes::Tolerance::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PressureMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeToleranceWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PressureMeasurement::Attributes::Tolerance::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PressureMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeToleranceWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = PressureMeasurement::Attributes::Tolerance::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeScaledValueWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PressureMeasurement::Attributes::ScaledValue::TypeInfo;
            auto successFn = Callback<NullableInt16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PressureMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeScaledValueWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PressureMeasurement::Attributes::ScaledValue::TypeInfo;
            auto successFn = Callback<NullableInt16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PressureMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeScaledValueWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = PressureMeasurement::Attributes::ScaledValue::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeMinScaledValueWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PressureMeasurement::Attributes::MinScaledValue::TypeInfo;
            auto successFn = Callback<NullableInt16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PressureMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeMinScaledValueWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PressureMeasurement::Attributes::MinScaledValue::TypeInfo;
            auto successFn = Callback<NullableInt16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PressureMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeMinScaledValueWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = PressureMeasurement::Attributes::MinScaledValue::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeMaxScaledValueWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PressureMeasurement::Attributes::MaxScaledValue::TypeInfo;
            auto successFn = Callback<NullableInt16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PressureMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeMaxScaledValueWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PressureMeasurement::Attributes::MaxScaledValue::TypeInfo;
            auto successFn = Callback<NullableInt16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PressureMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeMaxScaledValueWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = PressureMeasurement::Attributes::MaxScaledValue::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeScaledToleranceWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PressureMeasurement::Attributes::ScaledTolerance::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PressureMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeScaledToleranceWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PressureMeasurement::Attributes::ScaledTolerance::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PressureMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeScaledToleranceWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = PressureMeasurement::Attributes::ScaledTolerance::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeScaleWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PressureMeasurement::Attributes::Scale::TypeInfo;
            auto successFn = Callback<Int8sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PressureMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeScaleWithMinInterval:(NSNumber * _Nonnull)minInterval
                                   maxInterval:(NSNumber * _Nonnull)maxInterval
                                        params:(MTRSubscribeParams * _Nullable)params
                       subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PressureMeasurement::Attributes::Scale::TypeInfo;
            auto successFn = Callback<Int8sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PressureMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeScaleWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                    endpoint:(NSNumber *)endpoint
                                       queue:(dispatch_queue_t)queue
                           completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = PressureMeasurement::Attributes::Scale::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRPressureMeasurementGeneratedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PressureMeasurement::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<PressureMeasurementGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PressureMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRPressureMeasurementGeneratedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PressureMeasurement::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<PressureMeasurementGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PressureMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRPressureMeasurementGeneratedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRPressureMeasurementGeneratedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PressureMeasurement::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<PressureMeasurementGeneratedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRPressureMeasurementAcceptedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PressureMeasurement::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<PressureMeasurementAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PressureMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRPressureMeasurementAcceptedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PressureMeasurement::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<PressureMeasurementAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PressureMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRPressureMeasurementAcceptedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRPressureMeasurementAcceptedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PressureMeasurement::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<PressureMeasurementAcceptedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRPressureMeasurementAttributeListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PressureMeasurement::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<PressureMeasurementAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PressureMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRPressureMeasurementAttributeListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PressureMeasurement::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<PressureMeasurementAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PressureMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRPressureMeasurementAttributeListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRPressureMeasurementAttributeListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = PressureMeasurement::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<PressureMeasurementAttributeListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PressureMeasurement::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PressureMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PressureMeasurement::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PressureMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = PressureMeasurement::Attributes::FeatureMap::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = PressureMeasurement::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::PressureMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = PressureMeasurement::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::PressureMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = PressureMeasurement::Attributes::ClusterRevision::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

@end

@implementation MTRBaseClusterFlowMeasurement

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = endpoint;
    }
    return self;
}

- (void)readAttributeMeasuredValueWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = FlowMeasurement::Attributes::MeasuredValue::TypeInfo;
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::FlowMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeMeasuredValueWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = FlowMeasurement::Attributes::MeasuredValue::TypeInfo;
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::FlowMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeMeasuredValueWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = FlowMeasurement::Attributes::MeasuredValue::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeMinMeasuredValueWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = FlowMeasurement::Attributes::MinMeasuredValue::TypeInfo;
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::FlowMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeMinMeasuredValueWithMinInterval:(NSNumber * _Nonnull)minInterval
                                              maxInterval:(NSNumber * _Nonnull)maxInterval
                                                   params:(MTRSubscribeParams * _Nullable)params
                                  subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                            reportHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = FlowMeasurement::Attributes::MinMeasuredValue::TypeInfo;
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::FlowMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeMinMeasuredValueWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = FlowMeasurement::Attributes::MinMeasuredValue::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeMaxMeasuredValueWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = FlowMeasurement::Attributes::MaxMeasuredValue::TypeInfo;
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::FlowMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeMaxMeasuredValueWithMinInterval:(NSNumber * _Nonnull)minInterval
                                              maxInterval:(NSNumber * _Nonnull)maxInterval
                                                   params:(MTRSubscribeParams * _Nullable)params
                                  subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                            reportHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = FlowMeasurement::Attributes::MaxMeasuredValue::TypeInfo;
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::FlowMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeMaxMeasuredValueWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = FlowMeasurement::Attributes::MaxMeasuredValue::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeToleranceWithCompletionHandler:(void (^)(
                                                        NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = FlowMeasurement::Attributes::Tolerance::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::FlowMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeToleranceWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = FlowMeasurement::Attributes::Tolerance::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::FlowMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeToleranceWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = FlowMeasurement::Attributes::Tolerance::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRFlowMeasurementGeneratedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = FlowMeasurement::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<FlowMeasurementGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::FlowMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRFlowMeasurementGeneratedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = FlowMeasurement::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<FlowMeasurementGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::FlowMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRFlowMeasurementGeneratedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRFlowMeasurementGeneratedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = FlowMeasurement::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<FlowMeasurementGeneratedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRFlowMeasurementAcceptedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = FlowMeasurement::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<FlowMeasurementAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::FlowMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRFlowMeasurementAcceptedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = FlowMeasurement::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<FlowMeasurementAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::FlowMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRFlowMeasurementAcceptedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRFlowMeasurementAcceptedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = FlowMeasurement::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<FlowMeasurementAcceptedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRFlowMeasurementAttributeListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = FlowMeasurement::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<FlowMeasurementAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::FlowMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRFlowMeasurementAttributeListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = FlowMeasurement::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<FlowMeasurementAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::FlowMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRFlowMeasurementAttributeListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRFlowMeasurementAttributeListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = FlowMeasurement::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<FlowMeasurementAttributeListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = FlowMeasurement::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::FlowMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = FlowMeasurement::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::FlowMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = FlowMeasurement::Attributes::FeatureMap::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = FlowMeasurement::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::FlowMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = FlowMeasurement::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::FlowMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = FlowMeasurement::Attributes::ClusterRevision::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

@end

@implementation MTRBaseClusterRelativeHumidityMeasurement

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = endpoint;
    }
    return self;
}

- (void)readAttributeMeasuredValueWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = RelativeHumidityMeasurement::Attributes::MeasuredValue::TypeInfo;
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::RelativeHumidityMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeMeasuredValueWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = RelativeHumidityMeasurement::Attributes::MeasuredValue::TypeInfo;
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::RelativeHumidityMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeMeasuredValueWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = RelativeHumidityMeasurement::Attributes::MeasuredValue::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeMinMeasuredValueWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = RelativeHumidityMeasurement::Attributes::MinMeasuredValue::TypeInfo;
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::RelativeHumidityMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeMinMeasuredValueWithMinInterval:(NSNumber * _Nonnull)minInterval
                                              maxInterval:(NSNumber * _Nonnull)maxInterval
                                                   params:(MTRSubscribeParams * _Nullable)params
                                  subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                            reportHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = RelativeHumidityMeasurement::Attributes::MinMeasuredValue::TypeInfo;
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::RelativeHumidityMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeMinMeasuredValueWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = RelativeHumidityMeasurement::Attributes::MinMeasuredValue::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeMaxMeasuredValueWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = RelativeHumidityMeasurement::Attributes::MaxMeasuredValue::TypeInfo;
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::RelativeHumidityMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeMaxMeasuredValueWithMinInterval:(NSNumber * _Nonnull)minInterval
                                              maxInterval:(NSNumber * _Nonnull)maxInterval
                                                   params:(MTRSubscribeParams * _Nullable)params
                                  subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                            reportHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = RelativeHumidityMeasurement::Attributes::MaxMeasuredValue::TypeInfo;
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::RelativeHumidityMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeMaxMeasuredValueWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = RelativeHumidityMeasurement::Attributes::MaxMeasuredValue::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeToleranceWithCompletionHandler:(void (^)(
                                                        NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = RelativeHumidityMeasurement::Attributes::Tolerance::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::RelativeHumidityMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeToleranceWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = RelativeHumidityMeasurement::Attributes::Tolerance::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::RelativeHumidityMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeToleranceWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = RelativeHumidityMeasurement::Attributes::Tolerance::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRRelativeHumidityMeasurementGeneratedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device,
        completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = RelativeHumidityMeasurement::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn
                = Callback<RelativeHumidityMeasurementGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::RelativeHumidityMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRRelativeHumidityMeasurementGeneratedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = RelativeHumidityMeasurement::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn
                = Callback<RelativeHumidityMeasurementGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::RelativeHumidityMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRRelativeHumidityMeasurementGeneratedCommandListListAttributeCallbackSubscriptionBridge::
                    OnSubscriptionEstablished,
                nil, params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRRelativeHumidityMeasurementGeneratedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = RelativeHumidityMeasurement::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn
                    = Callback<RelativeHumidityMeasurementGeneratedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRRelativeHumidityMeasurementAcceptedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device,
        completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = RelativeHumidityMeasurement::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<RelativeHumidityMeasurementAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::RelativeHumidityMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRRelativeHumidityMeasurementAcceptedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = RelativeHumidityMeasurement::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<RelativeHumidityMeasurementAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::RelativeHumidityMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRRelativeHumidityMeasurementAcceptedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished,
                nil, params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRRelativeHumidityMeasurementAcceptedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = RelativeHumidityMeasurement::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn
                    = Callback<RelativeHumidityMeasurementAcceptedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRRelativeHumidityMeasurementAttributeListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = RelativeHumidityMeasurement::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<RelativeHumidityMeasurementAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::RelativeHumidityMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRRelativeHumidityMeasurementAttributeListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = RelativeHumidityMeasurement::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<RelativeHumidityMeasurementAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::RelativeHumidityMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRRelativeHumidityMeasurementAttributeListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRRelativeHumidityMeasurementAttributeListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = RelativeHumidityMeasurement::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<RelativeHumidityMeasurementAttributeListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = RelativeHumidityMeasurement::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::RelativeHumidityMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = RelativeHumidityMeasurement::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::RelativeHumidityMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = RelativeHumidityMeasurement::Attributes::FeatureMap::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = RelativeHumidityMeasurement::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::RelativeHumidityMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = RelativeHumidityMeasurement::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::RelativeHumidityMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = RelativeHumidityMeasurement::Attributes::ClusterRevision::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

@end

@implementation MTRBaseClusterOccupancySensing

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = endpoint;
    }
    return self;
}

- (void)readAttributeOccupancyWithCompletionHandler:(void (^)(
                                                        NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = OccupancySensing::Attributes::Occupancy::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OccupancySensingCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeOccupancyWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = OccupancySensing::Attributes::Occupancy::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::OccupancySensingCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeOccupancyWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = OccupancySensing::Attributes::Occupancy::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeOccupancySensorTypeWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = OccupancySensing::Attributes::OccupancySensorType::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OccupancySensingCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeOccupancySensorTypeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = OccupancySensing::Attributes::OccupancySensorType::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::OccupancySensingCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeOccupancySensorTypeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = OccupancySensing::Attributes::OccupancySensorType::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeOccupancySensorTypeBitmapWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = OccupancySensing::Attributes::OccupancySensorTypeBitmap::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OccupancySensingCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeOccupancySensorTypeBitmapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                                            params:(MTRSubscribeParams * _Nullable)params
                                           subscriptionEstablished:
                                               (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                     reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = OccupancySensing::Attributes::OccupancySensorTypeBitmap::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::OccupancySensingCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeOccupancySensorTypeBitmapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                        endpoint:(NSNumber *)endpoint
                                                           queue:(dispatch_queue_t)queue
                                               completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = OccupancySensing::Attributes::OccupancySensorTypeBitmap::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributePirOccupiedToUnoccupiedDelayWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = OccupancySensing::Attributes::PirOccupiedToUnoccupiedDelay::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OccupancySensingCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributePirOccupiedToUnoccupiedDelayWithValue:(NSNumber * _Nonnull)value
                                          completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributePirOccupiedToUnoccupiedDelayWithValue:(NSNumber * _Nonnull) value
                                                       params:nil
                                            completionHandler:completionHandler];
}
- (void)writeAttributePirOccupiedToUnoccupiedDelayWithValue:(NSNumber * _Nonnull)value
                                                     params:(MTRWriteParams * _Nullable)params
                                          completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = OccupancySensing::Attributes::PirOccupiedToUnoccupiedDelay::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::OccupancySensingCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributePirOccupiedToUnoccupiedDelayWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                                               params:(MTRSubscribeParams * _Nullable)params
                                              subscriptionEstablished:
                                                  (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                        reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                          NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = OccupancySensing::Attributes::PirOccupiedToUnoccupiedDelay::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::OccupancySensingCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributePirOccupiedToUnoccupiedDelayWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                           endpoint:(NSNumber *)endpoint
                                                              queue:(dispatch_queue_t)queue
                                                  completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = OccupancySensing::Attributes::PirOccupiedToUnoccupiedDelay::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributePirUnoccupiedToOccupiedDelayWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = OccupancySensing::Attributes::PirUnoccupiedToOccupiedDelay::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OccupancySensingCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributePirUnoccupiedToOccupiedDelayWithValue:(NSNumber * _Nonnull)value
                                          completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributePirUnoccupiedToOccupiedDelayWithValue:(NSNumber * _Nonnull) value
                                                       params:nil
                                            completionHandler:completionHandler];
}
- (void)writeAttributePirUnoccupiedToOccupiedDelayWithValue:(NSNumber * _Nonnull)value
                                                     params:(MTRWriteParams * _Nullable)params
                                          completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = OccupancySensing::Attributes::PirUnoccupiedToOccupiedDelay::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::OccupancySensingCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributePirUnoccupiedToOccupiedDelayWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                                               params:(MTRSubscribeParams * _Nullable)params
                                              subscriptionEstablished:
                                                  (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                        reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                          NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = OccupancySensing::Attributes::PirUnoccupiedToOccupiedDelay::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::OccupancySensingCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributePirUnoccupiedToOccupiedDelayWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                           endpoint:(NSNumber *)endpoint
                                                              queue:(dispatch_queue_t)queue
                                                  completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = OccupancySensing::Attributes::PirUnoccupiedToOccupiedDelay::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributePirUnoccupiedToOccupiedThresholdWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                               NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = OccupancySensing::Attributes::PirUnoccupiedToOccupiedThreshold::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OccupancySensingCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributePirUnoccupiedToOccupiedThresholdWithValue:(NSNumber * _Nonnull)value
                                              completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributePirUnoccupiedToOccupiedThresholdWithValue:(NSNumber * _Nonnull) value
                                                           params:nil
                                                completionHandler:completionHandler];
}
- (void)writeAttributePirUnoccupiedToOccupiedThresholdWithValue:(NSNumber * _Nonnull)value
                                                         params:(MTRWriteParams * _Nullable)params
                                              completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = OccupancySensing::Attributes::PirUnoccupiedToOccupiedThreshold::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedCharValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::OccupancySensingCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributePirUnoccupiedToOccupiedThresholdWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                              maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                   params:(MTRSubscribeParams * _Nullable)params
                                                  subscriptionEstablished:
                                                      (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                            reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                              NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = OccupancySensing::Attributes::PirUnoccupiedToOccupiedThreshold::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::OccupancySensingCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributePirUnoccupiedToOccupiedThresholdWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                               endpoint:(NSNumber *)endpoint
                                                                  queue:(dispatch_queue_t)queue
                                                      completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                            NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = OccupancySensing::Attributes::PirUnoccupiedToOccupiedThreshold::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeUltrasonicOccupiedToUnoccupiedDelayWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                                  NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = OccupancySensing::Attributes::UltrasonicOccupiedToUnoccupiedDelay::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OccupancySensingCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeUltrasonicOccupiedToUnoccupiedDelayWithValue:(NSNumber * _Nonnull)value
                                                 completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeUltrasonicOccupiedToUnoccupiedDelayWithValue:(NSNumber * _Nonnull) value
                                                              params:nil
                                                   completionHandler:completionHandler];
}
- (void)writeAttributeUltrasonicOccupiedToUnoccupiedDelayWithValue:(NSNumber * _Nonnull)value
                                                            params:(MTRWriteParams * _Nullable)params
                                                 completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = OccupancySensing::Attributes::UltrasonicOccupiedToUnoccupiedDelay::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::OccupancySensingCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeUltrasonicOccupiedToUnoccupiedDelayWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                      params:(MTRSubscribeParams * _Nullable)params
                                                     subscriptionEstablished:
                                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                               reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                                 NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = OccupancySensing::Attributes::UltrasonicOccupiedToUnoccupiedDelay::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::OccupancySensingCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeUltrasonicOccupiedToUnoccupiedDelayWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                                  endpoint:(NSNumber *)endpoint
                                                                     queue:(dispatch_queue_t)queue
                                                         completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                               NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = OccupancySensing::Attributes::UltrasonicOccupiedToUnoccupiedDelay::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeUltrasonicUnoccupiedToOccupiedDelayWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                                  NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = OccupancySensing::Attributes::UltrasonicUnoccupiedToOccupiedDelay::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OccupancySensingCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeUltrasonicUnoccupiedToOccupiedDelayWithValue:(NSNumber * _Nonnull)value
                                                 completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeUltrasonicUnoccupiedToOccupiedDelayWithValue:(NSNumber * _Nonnull) value
                                                              params:nil
                                                   completionHandler:completionHandler];
}
- (void)writeAttributeUltrasonicUnoccupiedToOccupiedDelayWithValue:(NSNumber * _Nonnull)value
                                                            params:(MTRWriteParams * _Nullable)params
                                                 completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = OccupancySensing::Attributes::UltrasonicUnoccupiedToOccupiedDelay::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::OccupancySensingCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeUltrasonicUnoccupiedToOccupiedDelayWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                      params:(MTRSubscribeParams * _Nullable)params
                                                     subscriptionEstablished:
                                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                               reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                                 NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = OccupancySensing::Attributes::UltrasonicUnoccupiedToOccupiedDelay::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::OccupancySensingCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeUltrasonicUnoccupiedToOccupiedDelayWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                                  endpoint:(NSNumber *)endpoint
                                                                     queue:(dispatch_queue_t)queue
                                                         completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                               NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = OccupancySensing::Attributes::UltrasonicUnoccupiedToOccupiedDelay::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeUltrasonicUnoccupiedToOccupiedThresholdWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                                      NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = OccupancySensing::Attributes::UltrasonicUnoccupiedToOccupiedThreshold::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OccupancySensingCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeUltrasonicUnoccupiedToOccupiedThresholdWithValue:(NSNumber * _Nonnull)value
                                                     completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeUltrasonicUnoccupiedToOccupiedThresholdWithValue:(NSNumber * _Nonnull) value
                                                                  params:nil
                                                       completionHandler:completionHandler];
}
- (void)writeAttributeUltrasonicUnoccupiedToOccupiedThresholdWithValue:(NSNumber * _Nonnull)value
                                                                params:(MTRWriteParams * _Nullable)params
                                                     completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = OccupancySensing::Attributes::UltrasonicUnoccupiedToOccupiedThreshold::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedCharValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::OccupancySensingCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeUltrasonicUnoccupiedToOccupiedThresholdWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                                     maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                          params:(MTRSubscribeParams * _Nullable)params
                                                         subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)
                                                                                     subscriptionEstablishedHandler
                                                                   reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                                     NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = OccupancySensing::Attributes::UltrasonicUnoccupiedToOccupiedThreshold::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::OccupancySensingCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeUltrasonicUnoccupiedToOccupiedThresholdWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                                      endpoint:(NSNumber *)endpoint
                                                                         queue:(dispatch_queue_t)queue
                                                             completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                                   NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = OccupancySensing::Attributes::UltrasonicUnoccupiedToOccupiedThreshold::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributePhysicalContactOccupiedToUnoccupiedDelayWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                                       NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = OccupancySensing::Attributes::PhysicalContactOccupiedToUnoccupiedDelay::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OccupancySensingCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributePhysicalContactOccupiedToUnoccupiedDelayWithValue:(NSNumber * _Nonnull)value
                                                      completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributePhysicalContactOccupiedToUnoccupiedDelayWithValue:(NSNumber * _Nonnull) value
                                                                   params:nil
                                                        completionHandler:completionHandler];
}
- (void)writeAttributePhysicalContactOccupiedToUnoccupiedDelayWithValue:(NSNumber * _Nonnull)value
                                                                 params:(MTRWriteParams * _Nullable)params
                                                      completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = OccupancySensing::Attributes::PhysicalContactOccupiedToUnoccupiedDelay::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::OccupancySensingCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributePhysicalContactOccupiedToUnoccupiedDelayWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                           params:(MTRSubscribeParams * _Nullable)params
                                                          subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)
                                                                                      subscriptionEstablishedHandler
                                                                    reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                                      NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = OccupancySensing::Attributes::PhysicalContactOccupiedToUnoccupiedDelay::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::OccupancySensingCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributePhysicalContactOccupiedToUnoccupiedDelayWithAttributeCache:
            (MTRAttributeCacheContainer *)attributeCacheContainer
                                                                       endpoint:(NSNumber *)endpoint
                                                                          queue:(dispatch_queue_t)queue
                                                              completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                                    NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = OccupancySensing::Attributes::PhysicalContactOccupiedToUnoccupiedDelay::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributePhysicalContactUnoccupiedToOccupiedDelayWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                                       NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = OccupancySensing::Attributes::PhysicalContactUnoccupiedToOccupiedDelay::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OccupancySensingCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributePhysicalContactUnoccupiedToOccupiedDelayWithValue:(NSNumber * _Nonnull)value
                                                      completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributePhysicalContactUnoccupiedToOccupiedDelayWithValue:(NSNumber * _Nonnull) value
                                                                   params:nil
                                                        completionHandler:completionHandler];
}
- (void)writeAttributePhysicalContactUnoccupiedToOccupiedDelayWithValue:(NSNumber * _Nonnull)value
                                                                 params:(MTRWriteParams * _Nullable)params
                                                      completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = OccupancySensing::Attributes::PhysicalContactUnoccupiedToOccupiedDelay::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::OccupancySensingCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributePhysicalContactUnoccupiedToOccupiedDelayWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                           params:(MTRSubscribeParams * _Nullable)params
                                                          subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)
                                                                                      subscriptionEstablishedHandler
                                                                    reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                                      NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = OccupancySensing::Attributes::PhysicalContactUnoccupiedToOccupiedDelay::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::OccupancySensingCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributePhysicalContactUnoccupiedToOccupiedDelayWithAttributeCache:
            (MTRAttributeCacheContainer *)attributeCacheContainer
                                                                       endpoint:(NSNumber *)endpoint
                                                                          queue:(dispatch_queue_t)queue
                                                              completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                                    NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = OccupancySensing::Attributes::PhysicalContactUnoccupiedToOccupiedDelay::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributePhysicalContactUnoccupiedToOccupiedThresholdWithCompletionHandler:
    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = OccupancySensing::Attributes::PhysicalContactUnoccupiedToOccupiedThreshold::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OccupancySensingCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributePhysicalContactUnoccupiedToOccupiedThresholdWithValue:(NSNumber * _Nonnull)value
                                                          completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributePhysicalContactUnoccupiedToOccupiedThresholdWithValue:(NSNumber * _Nonnull) value
                                                                       params:nil
                                                            completionHandler:completionHandler];
}
- (void)writeAttributePhysicalContactUnoccupiedToOccupiedThresholdWithValue:(NSNumber * _Nonnull)value
                                                                     params:(MTRWriteParams * _Nullable)params
                                                          completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = OccupancySensing::Attributes::PhysicalContactUnoccupiedToOccupiedThreshold::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedCharValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::OccupancySensingCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributePhysicalContactUnoccupiedToOccupiedThresholdWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                               params:(MTRSubscribeParams * _Nullable)params
                                                              subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)
                                                                                          subscriptionEstablishedHandler
                                                                        reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                                          NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = OccupancySensing::Attributes::PhysicalContactUnoccupiedToOccupiedThreshold::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::OccupancySensingCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributePhysicalContactUnoccupiedToOccupiedThresholdWithAttributeCache:
            (MTRAttributeCacheContainer *)attributeCacheContainer
                                                                           endpoint:(NSNumber *)endpoint
                                                                              queue:(dispatch_queue_t)queue
                                                                  completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                                        NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = OccupancySensing::Attributes::PhysicalContactUnoccupiedToOccupiedThreshold::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTROccupancySensingGeneratedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = OccupancySensing::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<OccupancySensingGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OccupancySensingCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTROccupancySensingGeneratedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = OccupancySensing::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<OccupancySensingGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::OccupancySensingCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTROccupancySensingGeneratedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTROccupancySensingGeneratedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OccupancySensing::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<OccupancySensingGeneratedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTROccupancySensingAcceptedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = OccupancySensing::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<OccupancySensingAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OccupancySensingCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTROccupancySensingAcceptedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = OccupancySensing::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<OccupancySensingAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::OccupancySensingCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTROccupancySensingAcceptedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTROccupancySensingAcceptedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OccupancySensing::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<OccupancySensingAcceptedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTROccupancySensingAttributeListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = OccupancySensing::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<OccupancySensingAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OccupancySensingCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTROccupancySensingAttributeListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = OccupancySensing::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<OccupancySensingAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::OccupancySensingCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTROccupancySensingAttributeListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTROccupancySensingAttributeListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = OccupancySensing::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<OccupancySensingAttributeListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = OccupancySensing::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OccupancySensingCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = OccupancySensing::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::OccupancySensingCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = OccupancySensing::Attributes::FeatureMap::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = OccupancySensing::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::OccupancySensingCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = OccupancySensing::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::OccupancySensingCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = OccupancySensing::Attributes::ClusterRevision::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

@end

@implementation MTRBaseClusterWakeOnLan

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = endpoint;
    }
    return self;
}

- (void)readAttributeMACAddressWithCompletionHandler:(void (^)(
                                                         NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = WakeOnLan::Attributes::MACAddress::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::WakeOnLanCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeMACAddressWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRCharStringAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = WakeOnLan::Attributes::MACAddress::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::WakeOnLanCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRCharStringAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeMACAddressWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = WakeOnLan::Attributes::MACAddress::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRWakeOnLanGeneratedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = WakeOnLan::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<WakeOnLanGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::WakeOnLanCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRWakeOnLanGeneratedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = WakeOnLan::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<WakeOnLanGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::WakeOnLanCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRWakeOnLanGeneratedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRWakeOnLanGeneratedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WakeOnLan::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<WakeOnLanGeneratedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRWakeOnLanAcceptedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = WakeOnLan::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<WakeOnLanAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::WakeOnLanCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRWakeOnLanAcceptedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = WakeOnLan::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<WakeOnLanAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::WakeOnLanCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRWakeOnLanAcceptedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRWakeOnLanAcceptedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WakeOnLan::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<WakeOnLanAcceptedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRWakeOnLanAttributeListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = WakeOnLan::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<WakeOnLanAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::WakeOnLanCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRWakeOnLanAttributeListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = WakeOnLan::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<WakeOnLanAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::WakeOnLanCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRWakeOnLanAttributeListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRWakeOnLanAttributeListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = WakeOnLan::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<WakeOnLanAttributeListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = WakeOnLan::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::WakeOnLanCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = WakeOnLan::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::WakeOnLanCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = WakeOnLan::Attributes::FeatureMap::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = WakeOnLan::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::WakeOnLanCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = WakeOnLan::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::WakeOnLanCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = WakeOnLan::Attributes::ClusterRevision::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

@end

@implementation MTRBaseClusterChannel

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = endpoint;
    }
    return self;
}

- (void)changeChannelWithParams:(MTRChannelClusterChangeChannelParams *)params
              completionHandler:(void (^)(MTRChannelClusterChangeChannelResponseParams * _Nullable data,
                                    NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRChannelClusterChangeChannelResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            Channel::Commands::ChangeChannel::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.match = [self asCharSpan:params.match];

            auto successFn = Callback<ChannelClusterChangeChannelResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ChannelCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)changeChannelByNumberWithParams:(MTRChannelClusterChangeChannelByNumberParams *)params
                      completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            Channel::Commands::ChangeChannelByNumber::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.majorNumber = params.majorNumber.unsignedShortValue;
            request.minorNumber = params.minorNumber.unsignedShortValue;

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ChannelCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)skipChannelWithParams:(MTRChannelClusterSkipChannelParams *)params completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            Channel::Commands::SkipChannel::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.count = params.count.unsignedShortValue;

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ChannelCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)readAttributeChannelListWithCompletionHandler:(void (^)(
                                                          NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRChannelChannelListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Channel::Attributes::ChannelList::TypeInfo;
            auto successFn = Callback<ChannelChannelListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ChannelCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeChannelListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRChannelChannelListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Channel::Attributes::ChannelList::TypeInfo;
            auto successFn = Callback<ChannelChannelListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ChannelCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRChannelChannelListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeChannelListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRChannelChannelListListAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Channel::Attributes::ChannelList::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<ChannelChannelListListAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeLineupWithCompletionHandler:(void (^)(MTRChannelClusterLineupInfo * _Nullable value,
                                                     NSError * _Nullable error))completionHandler
{
    new MTRChannelLineupStructAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Channel::Attributes::Lineup::TypeInfo;
            auto successFn = Callback<ChannelLineupStructAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ChannelCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeLineupWithMinInterval:(NSNumber * _Nonnull)minInterval
                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                         params:(MTRSubscribeParams * _Nullable)params
                        subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                  reportHandler:(void (^)(MTRChannelClusterLineupInfo * _Nullable value,
                                                    NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRChannelLineupStructAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Channel::Attributes::Lineup::TypeInfo;
            auto successFn = Callback<ChannelLineupStructAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ChannelCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRChannelLineupStructAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeLineupWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                     endpoint:(NSNumber *)endpoint
                                        queue:(dispatch_queue_t)queue
                            completionHandler:(void (^)(MTRChannelClusterLineupInfo * _Nullable value,
                                                  NSError * _Nullable error))completionHandler
{
    new MTRChannelLineupStructAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Channel::Attributes::Lineup::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<ChannelLineupStructAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeCurrentChannelWithCompletionHandler:(void (^)(MTRChannelClusterChannelInfo * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    new MTRChannelCurrentChannelStructAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Channel::Attributes::CurrentChannel::TypeInfo;
            auto successFn = Callback<ChannelCurrentChannelStructAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ChannelCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeCurrentChannelWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:(void (^)(MTRChannelClusterChannelInfo * _Nullable value,
                                                            NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRChannelCurrentChannelStructAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Channel::Attributes::CurrentChannel::TypeInfo;
            auto successFn = Callback<ChannelCurrentChannelStructAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ChannelCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRChannelCurrentChannelStructAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeCurrentChannelWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:(void (^)(MTRChannelClusterChannelInfo * _Nullable value,
                                                          NSError * _Nullable error))completionHandler
{
    new MTRChannelCurrentChannelStructAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Channel::Attributes::CurrentChannel::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<ChannelCurrentChannelStructAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRChannelGeneratedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Channel::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<ChannelGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ChannelCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRChannelGeneratedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Channel::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<ChannelGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ChannelCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRChannelGeneratedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRChannelGeneratedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Channel::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<ChannelGeneratedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRChannelAcceptedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Channel::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<ChannelAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ChannelCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRChannelAcceptedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Channel::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<ChannelAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ChannelCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRChannelAcceptedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRChannelAcceptedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = Channel::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<ChannelAcceptedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRChannelAttributeListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Channel::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<ChannelAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ChannelCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRChannelAttributeListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Channel::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<ChannelAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ChannelCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRChannelAttributeListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRChannelAttributeListListAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Channel::Attributes::AttributeList::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<ChannelAttributeListListAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Channel::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ChannelCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Channel::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ChannelCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Channel::Attributes::FeatureMap::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = Channel::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ChannelCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = Channel::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ChannelCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = Channel::Attributes::ClusterRevision::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

@end

@implementation MTRBaseClusterTargetNavigator

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = endpoint;
    }
    return self;
}

- (void)navigateTargetWithParams:(MTRTargetNavigatorClusterNavigateTargetParams *)params
               completionHandler:(void (^)(MTRTargetNavigatorClusterNavigateTargetResponseParams * _Nullable data,
                                     NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRTargetNavigatorClusterNavigateTargetResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            TargetNavigator::Commands::NavigateTarget::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.target = params.target.unsignedCharValue;
            if (params.data != nil) {
                auto & definedValue_0 = request.data.Emplace();
                definedValue_0 = [self asCharSpan:params.data];
            }

            auto successFn = Callback<TargetNavigatorClusterNavigateTargetResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TargetNavigatorCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)readAttributeTargetListWithCompletionHandler:(void (^)(
                                                         NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRTargetNavigatorTargetListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TargetNavigator::Attributes::TargetList::TypeInfo;
            auto successFn = Callback<TargetNavigatorTargetListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TargetNavigatorCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeTargetListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRTargetNavigatorTargetListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TargetNavigator::Attributes::TargetList::TypeInfo;
            auto successFn = Callback<TargetNavigatorTargetListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TargetNavigatorCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRTargetNavigatorTargetListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeTargetListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRTargetNavigatorTargetListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TargetNavigator::Attributes::TargetList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<TargetNavigatorTargetListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeCurrentTargetWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TargetNavigator::Attributes::CurrentTarget::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TargetNavigatorCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeCurrentTargetWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TargetNavigator::Attributes::CurrentTarget::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TargetNavigatorCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeCurrentTargetWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TargetNavigator::Attributes::CurrentTarget::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRTargetNavigatorGeneratedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TargetNavigator::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<TargetNavigatorGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TargetNavigatorCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRTargetNavigatorGeneratedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TargetNavigator::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<TargetNavigatorGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TargetNavigatorCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRTargetNavigatorGeneratedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRTargetNavigatorGeneratedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TargetNavigator::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<TargetNavigatorGeneratedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRTargetNavigatorAcceptedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TargetNavigator::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<TargetNavigatorAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TargetNavigatorCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRTargetNavigatorAcceptedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TargetNavigator::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<TargetNavigatorAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TargetNavigatorCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRTargetNavigatorAcceptedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRTargetNavigatorAcceptedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TargetNavigator::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<TargetNavigatorAcceptedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRTargetNavigatorAttributeListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TargetNavigator::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<TargetNavigatorAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TargetNavigatorCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRTargetNavigatorAttributeListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TargetNavigator::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<TargetNavigatorAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TargetNavigatorCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRTargetNavigatorAttributeListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRTargetNavigatorAttributeListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TargetNavigator::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<TargetNavigatorAttributeListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TargetNavigator::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TargetNavigatorCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TargetNavigator::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TargetNavigatorCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TargetNavigator::Attributes::FeatureMap::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TargetNavigator::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TargetNavigatorCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TargetNavigator::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TargetNavigatorCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TargetNavigator::Attributes::ClusterRevision::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

@end

@implementation MTRBaseClusterMediaPlayback

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = endpoint;
    }
    return self;
}

- (void)playWithCompletionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data,
                                      NSError * _Nullable error))completionHandler
{
    [self playWithParams:nil completionHandler:completionHandler];
}
- (void)playWithParams:(MTRMediaPlaybackClusterPlayParams * _Nullable)params
     completionHandler:
         (void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRMediaPlaybackClusterPlaybackResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            MediaPlayback::Commands::Play::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }

            auto successFn = Callback<MediaPlaybackClusterPlaybackResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::MediaPlaybackCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)pauseWithCompletionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data,
                                       NSError * _Nullable error))completionHandler
{
    [self pauseWithParams:nil completionHandler:completionHandler];
}
- (void)pauseWithParams:(MTRMediaPlaybackClusterPauseParams * _Nullable)params
      completionHandler:
          (void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRMediaPlaybackClusterPlaybackResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            MediaPlayback::Commands::Pause::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }

            auto successFn = Callback<MediaPlaybackClusterPlaybackResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::MediaPlaybackCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)stopPlaybackWithCompletionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data,
                                              NSError * _Nullable error))completionHandler
{
    [self stopPlaybackWithParams:nil completionHandler:completionHandler];
}
- (void)stopPlaybackWithParams:(MTRMediaPlaybackClusterStopPlaybackParams * _Nullable)params
             completionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data,
                                   NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRMediaPlaybackClusterPlaybackResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            MediaPlayback::Commands::StopPlayback::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }

            auto successFn = Callback<MediaPlaybackClusterPlaybackResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::MediaPlaybackCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)startOverWithCompletionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data,
                                           NSError * _Nullable error))completionHandler
{
    [self startOverWithParams:nil completionHandler:completionHandler];
}
- (void)startOverWithParams:(MTRMediaPlaybackClusterStartOverParams * _Nullable)params
          completionHandler:
              (void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRMediaPlaybackClusterPlaybackResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            MediaPlayback::Commands::StartOver::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }

            auto successFn = Callback<MediaPlaybackClusterPlaybackResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::MediaPlaybackCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)previousWithCompletionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data,
                                          NSError * _Nullable error))completionHandler
{
    [self previousWithParams:nil completionHandler:completionHandler];
}
- (void)previousWithParams:(MTRMediaPlaybackClusterPreviousParams * _Nullable)params
         completionHandler:
             (void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRMediaPlaybackClusterPlaybackResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            MediaPlayback::Commands::Previous::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }

            auto successFn = Callback<MediaPlaybackClusterPlaybackResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::MediaPlaybackCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)nextWithCompletionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data,
                                      NSError * _Nullable error))completionHandler
{
    [self nextWithParams:nil completionHandler:completionHandler];
}
- (void)nextWithParams:(MTRMediaPlaybackClusterNextParams * _Nullable)params
     completionHandler:
         (void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRMediaPlaybackClusterPlaybackResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            MediaPlayback::Commands::Next::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }

            auto successFn = Callback<MediaPlaybackClusterPlaybackResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::MediaPlaybackCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)rewindWithCompletionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data,
                                        NSError * _Nullable error))completionHandler
{
    [self rewindWithParams:nil completionHandler:completionHandler];
}
- (void)rewindWithParams:(MTRMediaPlaybackClusterRewindParams * _Nullable)params
       completionHandler:
           (void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRMediaPlaybackClusterPlaybackResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            MediaPlayback::Commands::Rewind::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }

            auto successFn = Callback<MediaPlaybackClusterPlaybackResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::MediaPlaybackCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)fastForwardWithCompletionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data,
                                             NSError * _Nullable error))completionHandler
{
    [self fastForwardWithParams:nil completionHandler:completionHandler];
}
- (void)fastForwardWithParams:(MTRMediaPlaybackClusterFastForwardParams * _Nullable)params
            completionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data,
                                  NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRMediaPlaybackClusterPlaybackResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            MediaPlayback::Commands::FastForward::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }

            auto successFn = Callback<MediaPlaybackClusterPlaybackResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::MediaPlaybackCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)skipForwardWithParams:(MTRMediaPlaybackClusterSkipForwardParams *)params
            completionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data,
                                  NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRMediaPlaybackClusterPlaybackResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            MediaPlayback::Commands::SkipForward::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.deltaPositionMilliseconds = params.deltaPositionMilliseconds.unsignedLongLongValue;

            auto successFn = Callback<MediaPlaybackClusterPlaybackResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::MediaPlaybackCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)skipBackwardWithParams:(MTRMediaPlaybackClusterSkipBackwardParams *)params
             completionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data,
                                   NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRMediaPlaybackClusterPlaybackResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            MediaPlayback::Commands::SkipBackward::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.deltaPositionMilliseconds = params.deltaPositionMilliseconds.unsignedLongLongValue;

            auto successFn = Callback<MediaPlaybackClusterPlaybackResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::MediaPlaybackCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)seekWithParams:(MTRMediaPlaybackClusterSeekParams *)params
     completionHandler:
         (void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRMediaPlaybackClusterPlaybackResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            MediaPlayback::Commands::Seek::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.position = params.position.unsignedLongLongValue;

            auto successFn = Callback<MediaPlaybackClusterPlaybackResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::MediaPlaybackCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)readAttributeCurrentStateWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRMediaPlaybackClusterPlaybackStateEnumAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = MediaPlayback::Attributes::CurrentState::TypeInfo;
            auto successFn = Callback<MediaPlaybackClusterPlaybackStateEnumAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::MediaPlaybackCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeCurrentStateWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRMediaPlaybackClusterPlaybackStateEnumAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = MediaPlayback::Attributes::CurrentState::TypeInfo;
            auto successFn = Callback<MediaPlaybackClusterPlaybackStateEnumAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::MediaPlaybackCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRMediaPlaybackClusterPlaybackStateEnumAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeCurrentStateWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRMediaPlaybackClusterPlaybackStateEnumAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = MediaPlayback::Attributes::CurrentState::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<MediaPlaybackClusterPlaybackStateEnumAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeStartTimeWithCompletionHandler:(void (^)(
                                                        NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt64uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = MediaPlayback::Attributes::StartTime::TypeInfo;
            auto successFn = Callback<NullableInt64uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::MediaPlaybackCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeStartTimeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt64uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = MediaPlayback::Attributes::StartTime::TypeInfo;
            auto successFn = Callback<NullableInt64uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::MediaPlaybackCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt64uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeStartTimeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt64uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = MediaPlayback::Attributes::StartTime::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt64uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeDurationWithCompletionHandler:(void (^)(
                                                       NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt64uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = MediaPlayback::Attributes::Duration::TypeInfo;
            auto successFn = Callback<NullableInt64uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::MediaPlaybackCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeDurationWithMinInterval:(NSNumber * _Nonnull)minInterval
                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                           params:(MTRSubscribeParams * _Nullable)params
                          subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt64uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = MediaPlayback::Attributes::Duration::TypeInfo;
            auto successFn = Callback<NullableInt64uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::MediaPlaybackCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt64uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeDurationWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                       endpoint:(NSNumber *)endpoint
                                          queue:(dispatch_queue_t)queue
                              completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt64uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = MediaPlayback::Attributes::Duration::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt64uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeSampledPositionWithCompletionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackPosition * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRMediaPlaybackSampledPositionStructAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = MediaPlayback::Attributes::SampledPosition::TypeInfo;
            auto successFn = Callback<MediaPlaybackSampledPositionStructAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::MediaPlaybackCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeSampledPositionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:(void (^)(MTRMediaPlaybackClusterPlaybackPosition * _Nullable value,
                                                             NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRMediaPlaybackSampledPositionStructAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = MediaPlayback::Attributes::SampledPosition::TypeInfo;
            auto successFn = Callback<MediaPlaybackSampledPositionStructAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::MediaPlaybackCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRMediaPlaybackSampledPositionStructAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeSampledPositionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackPosition * _Nullable value,
                                                           NSError * _Nullable error))completionHandler
{
    new MTRMediaPlaybackSampledPositionStructAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = MediaPlayback::Attributes::SampledPosition::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<MediaPlaybackSampledPositionStructAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributePlaybackSpeedWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRFloatAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = MediaPlayback::Attributes::PlaybackSpeed::TypeInfo;
            auto successFn = Callback<FloatAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::MediaPlaybackCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributePlaybackSpeedWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRFloatAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = MediaPlayback::Attributes::PlaybackSpeed::TypeInfo;
            auto successFn = Callback<FloatAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::MediaPlaybackCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRFloatAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributePlaybackSpeedWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRFloatAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = MediaPlayback::Attributes::PlaybackSpeed::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<FloatAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeSeekRangeEndWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt64uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = MediaPlayback::Attributes::SeekRangeEnd::TypeInfo;
            auto successFn = Callback<NullableInt64uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::MediaPlaybackCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeSeekRangeEndWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt64uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = MediaPlayback::Attributes::SeekRangeEnd::TypeInfo;
            auto successFn = Callback<NullableInt64uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::MediaPlaybackCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt64uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeSeekRangeEndWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt64uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = MediaPlayback::Attributes::SeekRangeEnd::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt64uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeSeekRangeStartWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    new MTRNullableInt64uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = MediaPlayback::Attributes::SeekRangeStart::TypeInfo;
            auto successFn = Callback<NullableInt64uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::MediaPlaybackCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeSeekRangeStartWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt64uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = MediaPlayback::Attributes::SeekRangeStart::TypeInfo;
            auto successFn = Callback<NullableInt64uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::MediaPlaybackCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt64uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeSeekRangeStartWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt64uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = MediaPlayback::Attributes::SeekRangeStart::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt64uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRMediaPlaybackGeneratedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = MediaPlayback::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<MediaPlaybackGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::MediaPlaybackCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRMediaPlaybackGeneratedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = MediaPlayback::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<MediaPlaybackGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::MediaPlaybackCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRMediaPlaybackGeneratedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRMediaPlaybackGeneratedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = MediaPlayback::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<MediaPlaybackGeneratedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRMediaPlaybackAcceptedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = MediaPlayback::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<MediaPlaybackAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::MediaPlaybackCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRMediaPlaybackAcceptedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = MediaPlayback::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<MediaPlaybackAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::MediaPlaybackCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRMediaPlaybackAcceptedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRMediaPlaybackAcceptedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = MediaPlayback::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<MediaPlaybackAcceptedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRMediaPlaybackAttributeListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = MediaPlayback::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<MediaPlaybackAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::MediaPlaybackCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRMediaPlaybackAttributeListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = MediaPlayback::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<MediaPlaybackAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::MediaPlaybackCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRMediaPlaybackAttributeListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRMediaPlaybackAttributeListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = MediaPlayback::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<MediaPlaybackAttributeListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = MediaPlayback::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::MediaPlaybackCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = MediaPlayback::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::MediaPlaybackCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = MediaPlayback::Attributes::FeatureMap::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = MediaPlayback::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::MediaPlaybackCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = MediaPlayback::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::MediaPlaybackCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = MediaPlayback::Attributes::ClusterRevision::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

@end

@implementation MTRBaseClusterMediaInput

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = endpoint;
    }
    return self;
}

- (void)selectInputWithParams:(MTRMediaInputClusterSelectInputParams *)params completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            MediaInput::Commands::SelectInput::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.index = params.index.unsignedCharValue;

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::MediaInputCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)showInputStatusWithCompletionHandler:(StatusCompletion)completionHandler
{
    [self showInputStatusWithParams:nil completionHandler:completionHandler];
}
- (void)showInputStatusWithParams:(MTRMediaInputClusterShowInputStatusParams * _Nullable)params
                completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            MediaInput::Commands::ShowInputStatus::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::MediaInputCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)hideInputStatusWithCompletionHandler:(StatusCompletion)completionHandler
{
    [self hideInputStatusWithParams:nil completionHandler:completionHandler];
}
- (void)hideInputStatusWithParams:(MTRMediaInputClusterHideInputStatusParams * _Nullable)params
                completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            MediaInput::Commands::HideInputStatus::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::MediaInputCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)renameInputWithParams:(MTRMediaInputClusterRenameInputParams *)params completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            MediaInput::Commands::RenameInput::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.index = params.index.unsignedCharValue;
            request.name = [self asCharSpan:params.name];

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::MediaInputCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)readAttributeInputListWithCompletionHandler:(void (^)(
                                                        NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRMediaInputInputListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = MediaInput::Attributes::InputList::TypeInfo;
            auto successFn = Callback<MediaInputInputListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::MediaInputCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeInputListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRMediaInputInputListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = MediaInput::Attributes::InputList::TypeInfo;
            auto successFn = Callback<MediaInputInputListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::MediaInputCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRMediaInputInputListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeInputListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRMediaInputInputListListAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = MediaInput::Attributes::InputList::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<MediaInputInputListListAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeCurrentInputWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = MediaInput::Attributes::CurrentInput::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::MediaInputCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeCurrentInputWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = MediaInput::Attributes::CurrentInput::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::MediaInputCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeCurrentInputWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = MediaInput::Attributes::CurrentInput::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRMediaInputGeneratedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = MediaInput::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<MediaInputGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::MediaInputCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRMediaInputGeneratedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = MediaInput::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<MediaInputGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::MediaInputCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRMediaInputGeneratedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRMediaInputGeneratedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = MediaInput::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<MediaInputGeneratedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRMediaInputAcceptedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = MediaInput::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<MediaInputAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::MediaInputCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRMediaInputAcceptedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = MediaInput::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<MediaInputAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::MediaInputCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRMediaInputAcceptedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRMediaInputAcceptedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = MediaInput::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<MediaInputAcceptedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRMediaInputAttributeListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = MediaInput::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<MediaInputAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::MediaInputCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRMediaInputAttributeListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = MediaInput::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<MediaInputAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::MediaInputCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRMediaInputAttributeListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRMediaInputAttributeListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = MediaInput::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<MediaInputAttributeListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = MediaInput::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::MediaInputCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = MediaInput::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::MediaInputCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = MediaInput::Attributes::FeatureMap::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = MediaInput::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::MediaInputCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = MediaInput::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::MediaInputCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = MediaInput::Attributes::ClusterRevision::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

@end

@implementation MTRBaseClusterLowPower

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = endpoint;
    }
    return self;
}

- (void)sleepWithCompletionHandler:(StatusCompletion)completionHandler
{
    [self sleepWithParams:nil completionHandler:completionHandler];
}
- (void)sleepWithParams:(MTRLowPowerClusterSleepParams * _Nullable)params completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            LowPower::Commands::Sleep::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::LowPowerCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRLowPowerGeneratedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = LowPower::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<LowPowerGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::LowPowerCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRLowPowerGeneratedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = LowPower::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<LowPowerGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::LowPowerCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRLowPowerGeneratedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRLowPowerGeneratedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = LowPower::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<LowPowerGeneratedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRLowPowerAcceptedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = LowPower::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<LowPowerAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::LowPowerCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRLowPowerAcceptedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = LowPower::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<LowPowerAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::LowPowerCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRLowPowerAcceptedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRLowPowerAcceptedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = LowPower::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<LowPowerAcceptedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRLowPowerAttributeListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = LowPower::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<LowPowerAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::LowPowerCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRLowPowerAttributeListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = LowPower::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<LowPowerAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::LowPowerCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRLowPowerAttributeListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRLowPowerAttributeListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = LowPower::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<LowPowerAttributeListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = LowPower::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::LowPowerCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = LowPower::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::LowPowerCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = LowPower::Attributes::FeatureMap::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = LowPower::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::LowPowerCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = LowPower::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::LowPowerCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = LowPower::Attributes::ClusterRevision::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

@end

@implementation MTRBaseClusterKeypadInput

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = endpoint;
    }
    return self;
}

- (void)sendKeyWithParams:(MTRKeypadInputClusterSendKeyParams *)params
        completionHandler:
            (void (^)(MTRKeypadInputClusterSendKeyResponseParams * _Nullable data, NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRKeypadInputClusterSendKeyResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            KeypadInput::Commands::SendKey::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.keyCode = static_cast<std::remove_reference_t<decltype(request.keyCode)>>(params.keyCode.unsignedCharValue);

            auto successFn = Callback<KeypadInputClusterSendKeyResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::KeypadInputCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRKeypadInputGeneratedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = KeypadInput::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<KeypadInputGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::KeypadInputCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRKeypadInputGeneratedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = KeypadInput::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<KeypadInputGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::KeypadInputCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRKeypadInputGeneratedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRKeypadInputGeneratedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = KeypadInput::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<KeypadInputGeneratedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRKeypadInputAcceptedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = KeypadInput::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<KeypadInputAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::KeypadInputCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRKeypadInputAcceptedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = KeypadInput::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<KeypadInputAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::KeypadInputCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRKeypadInputAcceptedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRKeypadInputAcceptedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = KeypadInput::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<KeypadInputAcceptedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRKeypadInputAttributeListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = KeypadInput::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<KeypadInputAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::KeypadInputCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRKeypadInputAttributeListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = KeypadInput::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<KeypadInputAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::KeypadInputCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRKeypadInputAttributeListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRKeypadInputAttributeListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = KeypadInput::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<KeypadInputAttributeListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = KeypadInput::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::KeypadInputCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = KeypadInput::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::KeypadInputCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = KeypadInput::Attributes::FeatureMap::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = KeypadInput::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::KeypadInputCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = KeypadInput::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::KeypadInputCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = KeypadInput::Attributes::ClusterRevision::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

@end

@implementation MTRBaseClusterContentLauncher

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = endpoint;
    }
    return self;
}

- (void)launchContentWithParams:(MTRContentLauncherClusterLaunchContentParams *)params
              completionHandler:(void (^)(MTRContentLauncherClusterLaunchResponseParams * _Nullable data,
                                    NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRContentLauncherClusterLaunchResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            ContentLauncher::Commands::LaunchContent::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            {
                using ListType_1 = std::remove_reference_t<decltype(request.search.parameterList)>;
                using ListMemberType_1 = ListMemberTypeGetter<ListType_1>::Type;
                if (params.search.parameterList.count != 0) {
                    auto * listHolder_1 = new ListHolder<ListMemberType_1>(params.search.parameterList.count);
                    if (listHolder_1 == nullptr || listHolder_1->mList == nullptr) {
                        return CHIP_ERROR_INVALID_ARGUMENT;
                    }
                    listFreer.add(listHolder_1);
                    for (size_t i_1 = 0; i_1 < params.search.parameterList.count; ++i_1) {
                        if (![params.search.parameterList[i_1] isKindOfClass:[MTRContentLauncherClusterParameter class]]) {
                            // Wrong kind of value.
                            return CHIP_ERROR_INVALID_ARGUMENT;
                        }
                        auto element_1 = (MTRContentLauncherClusterParameter *) params.search.parameterList[i_1];
                        listHolder_1->mList[i_1].type
                            = static_cast<std::remove_reference_t<decltype(listHolder_1->mList[i_1].type)>>(
                                element_1.type.unsignedCharValue);
                        listHolder_1->mList[i_1].value = [self asCharSpan:element_1.value];
                        if (element_1.externalIDList != nil) {
                            auto & definedValue_3 = listHolder_1->mList[i_1].externalIDList.Emplace();
                            {
                                using ListType_4 = std::remove_reference_t<decltype(definedValue_3)>;
                                using ListMemberType_4 = ListMemberTypeGetter<ListType_4>::Type;
                                if (element_1.externalIDList.count != 0) {
                                    auto * listHolder_4 = new ListHolder<ListMemberType_4>(element_1.externalIDList.count);
                                    if (listHolder_4 == nullptr || listHolder_4->mList == nullptr) {
                                        return CHIP_ERROR_INVALID_ARGUMENT;
                                    }
                                    listFreer.add(listHolder_4);
                                    for (size_t i_4 = 0; i_4 < element_1.externalIDList.count; ++i_4) {
                                        if (![element_1.externalIDList[i_4]
                                                isKindOfClass:[MTRContentLauncherClusterAdditionalInfo class]]) {
                                            // Wrong kind of value.
                                            return CHIP_ERROR_INVALID_ARGUMENT;
                                        }
                                        auto element_4 = (MTRContentLauncherClusterAdditionalInfo *) element_1.externalIDList[i_4];
                                        listHolder_4->mList[i_4].name = [self asCharSpan:element_4.name];
                                        listHolder_4->mList[i_4].value = [self asCharSpan:element_4.value];
                                    }
                                    definedValue_3 = ListType_4(listHolder_4->mList, element_1.externalIDList.count);
                                } else {
                                    definedValue_3 = ListType_4();
                                }
                            }
                        }
                    }
                    request.search.parameterList = ListType_1(listHolder_1->mList, params.search.parameterList.count);
                } else {
                    request.search.parameterList = ListType_1();
                }
            }
            request.autoPlay = params.autoPlay.boolValue;
            if (params.data != nil) {
                auto & definedValue_0 = request.data.Emplace();
                definedValue_0 = [self asCharSpan:params.data];
            }

            auto successFn = Callback<ContentLauncherClusterLaunchResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ContentLauncherCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)launchURLWithParams:(MTRContentLauncherClusterLaunchURLParams *)params
          completionHandler:
              (void (^)(MTRContentLauncherClusterLaunchResponseParams * _Nullable data, NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRContentLauncherClusterLaunchResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            ContentLauncher::Commands::LaunchURL::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.contentURL = [self asCharSpan:params.contentURL];
            if (params.displayString != nil) {
                auto & definedValue_0 = request.displayString.Emplace();
                definedValue_0 = [self asCharSpan:params.displayString];
            }
            if (params.brandingInformation != nil) {
                auto & definedValue_0 = request.brandingInformation.Emplace();
                definedValue_0.providerName = [self asCharSpan:params.brandingInformation.providerName];
                if (params.brandingInformation.background != nil) {
                    auto & definedValue_2 = definedValue_0.background.Emplace();
                    if (params.brandingInformation.background.imageUrl != nil) {
                        auto & definedValue_4 = definedValue_2.imageUrl.Emplace();
                        definedValue_4 = [self asCharSpan:params.brandingInformation.background.imageUrl];
                    }
                    if (params.brandingInformation.background.color != nil) {
                        auto & definedValue_4 = definedValue_2.color.Emplace();
                        definedValue_4 = [self asCharSpan:params.brandingInformation.background.color];
                    }
                    if (params.brandingInformation.background.size != nil) {
                        auto & definedValue_4 = definedValue_2.size.Emplace();
                        definedValue_4.width = params.brandingInformation.background.size.width.doubleValue;
                        definedValue_4.height = params.brandingInformation.background.size.height.doubleValue;
                        definedValue_4.metric = static_cast<std::remove_reference_t<decltype(definedValue_4.metric)>>(
                            params.brandingInformation.background.size.metric.unsignedCharValue);
                    }
                }
                if (params.brandingInformation.logo != nil) {
                    auto & definedValue_2 = definedValue_0.logo.Emplace();
                    if (params.brandingInformation.logo.imageUrl != nil) {
                        auto & definedValue_4 = definedValue_2.imageUrl.Emplace();
                        definedValue_4 = [self asCharSpan:params.brandingInformation.logo.imageUrl];
                    }
                    if (params.brandingInformation.logo.color != nil) {
                        auto & definedValue_4 = definedValue_2.color.Emplace();
                        definedValue_4 = [self asCharSpan:params.brandingInformation.logo.color];
                    }
                    if (params.brandingInformation.logo.size != nil) {
                        auto & definedValue_4 = definedValue_2.size.Emplace();
                        definedValue_4.width = params.brandingInformation.logo.size.width.doubleValue;
                        definedValue_4.height = params.brandingInformation.logo.size.height.doubleValue;
                        definedValue_4.metric = static_cast<std::remove_reference_t<decltype(definedValue_4.metric)>>(
                            params.brandingInformation.logo.size.metric.unsignedCharValue);
                    }
                }
                if (params.brandingInformation.progressBar != nil) {
                    auto & definedValue_2 = definedValue_0.progressBar.Emplace();
                    if (params.brandingInformation.progressBar.imageUrl != nil) {
                        auto & definedValue_4 = definedValue_2.imageUrl.Emplace();
                        definedValue_4 = [self asCharSpan:params.brandingInformation.progressBar.imageUrl];
                    }
                    if (params.brandingInformation.progressBar.color != nil) {
                        auto & definedValue_4 = definedValue_2.color.Emplace();
                        definedValue_4 = [self asCharSpan:params.brandingInformation.progressBar.color];
                    }
                    if (params.brandingInformation.progressBar.size != nil) {
                        auto & definedValue_4 = definedValue_2.size.Emplace();
                        definedValue_4.width = params.brandingInformation.progressBar.size.width.doubleValue;
                        definedValue_4.height = params.brandingInformation.progressBar.size.height.doubleValue;
                        definedValue_4.metric = static_cast<std::remove_reference_t<decltype(definedValue_4.metric)>>(
                            params.brandingInformation.progressBar.size.metric.unsignedCharValue);
                    }
                }
                if (params.brandingInformation.splash != nil) {
                    auto & definedValue_2 = definedValue_0.splash.Emplace();
                    if (params.brandingInformation.splash.imageUrl != nil) {
                        auto & definedValue_4 = definedValue_2.imageUrl.Emplace();
                        definedValue_4 = [self asCharSpan:params.brandingInformation.splash.imageUrl];
                    }
                    if (params.brandingInformation.splash.color != nil) {
                        auto & definedValue_4 = definedValue_2.color.Emplace();
                        definedValue_4 = [self asCharSpan:params.brandingInformation.splash.color];
                    }
                    if (params.brandingInformation.splash.size != nil) {
                        auto & definedValue_4 = definedValue_2.size.Emplace();
                        definedValue_4.width = params.brandingInformation.splash.size.width.doubleValue;
                        definedValue_4.height = params.brandingInformation.splash.size.height.doubleValue;
                        definedValue_4.metric = static_cast<std::remove_reference_t<decltype(definedValue_4.metric)>>(
                            params.brandingInformation.splash.size.metric.unsignedCharValue);
                    }
                }
                if (params.brandingInformation.waterMark != nil) {
                    auto & definedValue_2 = definedValue_0.waterMark.Emplace();
                    if (params.brandingInformation.waterMark.imageUrl != nil) {
                        auto & definedValue_4 = definedValue_2.imageUrl.Emplace();
                        definedValue_4 = [self asCharSpan:params.brandingInformation.waterMark.imageUrl];
                    }
                    if (params.brandingInformation.waterMark.color != nil) {
                        auto & definedValue_4 = definedValue_2.color.Emplace();
                        definedValue_4 = [self asCharSpan:params.brandingInformation.waterMark.color];
                    }
                    if (params.brandingInformation.waterMark.size != nil) {
                        auto & definedValue_4 = definedValue_2.size.Emplace();
                        definedValue_4.width = params.brandingInformation.waterMark.size.width.doubleValue;
                        definedValue_4.height = params.brandingInformation.waterMark.size.height.doubleValue;
                        definedValue_4.metric = static_cast<std::remove_reference_t<decltype(definedValue_4.metric)>>(
                            params.brandingInformation.waterMark.size.metric.unsignedCharValue);
                    }
                }
            }

            auto successFn = Callback<ContentLauncherClusterLaunchResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ContentLauncherCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)readAttributeAcceptHeaderWithCompletionHandler:(void (^)(
                                                           NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRContentLauncherAcceptHeaderListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ContentLauncher::Attributes::AcceptHeader::TypeInfo;
            auto successFn = Callback<ContentLauncherAcceptHeaderListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ContentLauncherCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcceptHeaderWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRContentLauncherAcceptHeaderListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ContentLauncher::Attributes::AcceptHeader::TypeInfo;
            auto successFn = Callback<ContentLauncherAcceptHeaderListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ContentLauncherCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRContentLauncherAcceptHeaderListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcceptHeaderWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRContentLauncherAcceptHeaderListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ContentLauncher::Attributes::AcceptHeader::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<ContentLauncherAcceptHeaderListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeSupportedStreamingProtocolsWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                          NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ContentLauncher::Attributes::SupportedStreamingProtocols::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ContentLauncherCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeSupportedStreamingProtocolsWithValue:(NSNumber * _Nonnull)value
                                         completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeSupportedStreamingProtocolsWithValue:(NSNumber * _Nonnull) value
                                                      params:nil
                                           completionHandler:completionHandler];
}
- (void)writeAttributeSupportedStreamingProtocolsWithValue:(NSNumber * _Nonnull)value
                                                    params:(MTRWriteParams * _Nullable)params
                                         completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = ContentLauncher::Attributes::SupportedStreamingProtocols::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedIntValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ContentLauncherCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeSupportedStreamingProtocolsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                                              params:(MTRSubscribeParams * _Nullable)params
                                             subscriptionEstablished:
                                                 (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                       reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ContentLauncher::Attributes::SupportedStreamingProtocols::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ContentLauncherCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeSupportedStreamingProtocolsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                          endpoint:(NSNumber *)endpoint
                                                             queue:(dispatch_queue_t)queue
                                                 completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ContentLauncher::Attributes::SupportedStreamingProtocols::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRContentLauncherGeneratedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ContentLauncher::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<ContentLauncherGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ContentLauncherCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRContentLauncherGeneratedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ContentLauncher::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<ContentLauncherGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ContentLauncherCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRContentLauncherGeneratedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRContentLauncherGeneratedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ContentLauncher::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<ContentLauncherGeneratedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRContentLauncherAcceptedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ContentLauncher::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<ContentLauncherAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ContentLauncherCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRContentLauncherAcceptedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ContentLauncher::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<ContentLauncherAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ContentLauncherCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRContentLauncherAcceptedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRContentLauncherAcceptedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ContentLauncher::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<ContentLauncherAcceptedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRContentLauncherAttributeListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ContentLauncher::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<ContentLauncherAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ContentLauncherCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRContentLauncherAttributeListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ContentLauncher::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<ContentLauncherAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ContentLauncherCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRContentLauncherAttributeListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRContentLauncherAttributeListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ContentLauncher::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<ContentLauncherAttributeListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ContentLauncher::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ContentLauncherCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ContentLauncher::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ContentLauncherCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ContentLauncher::Attributes::FeatureMap::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ContentLauncher::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ContentLauncherCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ContentLauncher::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ContentLauncherCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ContentLauncher::Attributes::ClusterRevision::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

@end

@implementation MTRBaseClusterAudioOutput

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = endpoint;
    }
    return self;
}

- (void)selectOutputWithParams:(MTRAudioOutputClusterSelectOutputParams *)params
             completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            AudioOutput::Commands::SelectOutput::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.index = params.index.unsignedCharValue;

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::AudioOutputCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)renameOutputWithParams:(MTRAudioOutputClusterRenameOutputParams *)params
             completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            AudioOutput::Commands::RenameOutput::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.index = params.index.unsignedCharValue;
            request.name = [self asCharSpan:params.name];

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::AudioOutputCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)readAttributeOutputListWithCompletionHandler:(void (^)(
                                                         NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRAudioOutputOutputListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = AudioOutput::Attributes::OutputList::TypeInfo;
            auto successFn = Callback<AudioOutputOutputListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::AudioOutputCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeOutputListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRAudioOutputOutputListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = AudioOutput::Attributes::OutputList::TypeInfo;
            auto successFn = Callback<AudioOutputOutputListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::AudioOutputCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRAudioOutputOutputListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeOutputListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRAudioOutputOutputListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = AudioOutput::Attributes::OutputList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<AudioOutputOutputListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeCurrentOutputWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = AudioOutput::Attributes::CurrentOutput::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::AudioOutputCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeCurrentOutputWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = AudioOutput::Attributes::CurrentOutput::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::AudioOutputCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeCurrentOutputWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = AudioOutput::Attributes::CurrentOutput::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRAudioOutputGeneratedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = AudioOutput::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<AudioOutputGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::AudioOutputCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRAudioOutputGeneratedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = AudioOutput::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<AudioOutputGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::AudioOutputCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRAudioOutputGeneratedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRAudioOutputGeneratedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = AudioOutput::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<AudioOutputGeneratedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRAudioOutputAcceptedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = AudioOutput::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<AudioOutputAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::AudioOutputCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRAudioOutputAcceptedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = AudioOutput::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<AudioOutputAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::AudioOutputCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRAudioOutputAcceptedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRAudioOutputAcceptedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = AudioOutput::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<AudioOutputAcceptedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRAudioOutputAttributeListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = AudioOutput::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<AudioOutputAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::AudioOutputCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRAudioOutputAttributeListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = AudioOutput::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<AudioOutputAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::AudioOutputCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRAudioOutputAttributeListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRAudioOutputAttributeListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = AudioOutput::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<AudioOutputAttributeListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = AudioOutput::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::AudioOutputCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = AudioOutput::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::AudioOutputCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = AudioOutput::Attributes::FeatureMap::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = AudioOutput::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::AudioOutputCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = AudioOutput::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::AudioOutputCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = AudioOutput::Attributes::ClusterRevision::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

@end

@implementation MTRBaseClusterApplicationLauncher

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = endpoint;
    }
    return self;
}

- (void)launchAppWithParams:(MTRApplicationLauncherClusterLaunchAppParams *)params
          completionHandler:(void (^)(MTRApplicationLauncherClusterLauncherResponseParams * _Nullable data,
                                NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRApplicationLauncherClusterLauncherResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            ApplicationLauncher::Commands::LaunchApp::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.application.catalogVendorId = params.application.catalogVendorId.unsignedShortValue;
            request.application.applicationId = [self asCharSpan:params.application.applicationId];
            if (params.data != nil) {
                auto & definedValue_0 = request.data.Emplace();
                definedValue_0 = [self asByteSpan:params.data];
            }

            auto successFn = Callback<ApplicationLauncherClusterLauncherResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ApplicationLauncherCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)stopAppWithParams:(MTRApplicationLauncherClusterStopAppParams *)params
        completionHandler:(void (^)(MTRApplicationLauncherClusterLauncherResponseParams * _Nullable data,
                              NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRApplicationLauncherClusterLauncherResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            ApplicationLauncher::Commands::StopApp::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.application.catalogVendorId = params.application.catalogVendorId.unsignedShortValue;
            request.application.applicationId = [self asCharSpan:params.application.applicationId];

            auto successFn = Callback<ApplicationLauncherClusterLauncherResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ApplicationLauncherCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)hideAppWithParams:(MTRApplicationLauncherClusterHideAppParams *)params
        completionHandler:(void (^)(MTRApplicationLauncherClusterLauncherResponseParams * _Nullable data,
                              NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRApplicationLauncherClusterLauncherResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            ApplicationLauncher::Commands::HideApp::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.application.catalogVendorId = params.application.catalogVendorId.unsignedShortValue;
            request.application.applicationId = [self asCharSpan:params.application.applicationId];

            auto successFn = Callback<ApplicationLauncherClusterLauncherResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ApplicationLauncherCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)readAttributeCatalogListWithCompletionHandler:(void (^)(
                                                          NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRApplicationLauncherCatalogListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ApplicationLauncher::Attributes::CatalogList::TypeInfo;
            auto successFn = Callback<ApplicationLauncherCatalogListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ApplicationLauncherCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeCatalogListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRApplicationLauncherCatalogListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ApplicationLauncher::Attributes::CatalogList::TypeInfo;
            auto successFn = Callback<ApplicationLauncherCatalogListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ApplicationLauncherCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRApplicationLauncherCatalogListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeCatalogListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRApplicationLauncherCatalogListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ApplicationLauncher::Attributes::CatalogList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<ApplicationLauncherCatalogListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeCurrentAppWithCompletionHandler:(void (^)(MTRApplicationLauncherClusterApplicationEP * _Nullable value,
                                                         NSError * _Nullable error))completionHandler
{
    new MTRApplicationLauncherCurrentAppStructAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ApplicationLauncher::Attributes::CurrentApp::TypeInfo;
            auto successFn = Callback<ApplicationLauncherCurrentAppStructAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ApplicationLauncherCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeCurrentAppWithValue:(MTRApplicationLauncherClusterApplicationEP * _Nullable)value
                        completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeCurrentAppWithValue:(MTRApplicationLauncherClusterApplicationEP * _Nullable) value
                                     params:nil
                          completionHandler:completionHandler];
}
- (void)writeAttributeCurrentAppWithValue:(MTRApplicationLauncherClusterApplicationEP * _Nullable)value
                                   params:(MTRWriteParams * _Nullable)params
                        completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = ApplicationLauncher::Attributes::CurrentApp::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0.application.catalogVendorId = value.application.catalogVendorId.unsignedShortValue;
                nonNullValue_0.application.applicationId = [self asCharSpan:value.application.applicationId];
                if (value.endpoint != nil) {
                    auto & definedValue_2 = nonNullValue_0.endpoint.Emplace();
                    definedValue_2 = value.endpoint.unsignedShortValue;
                }
            }
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ApplicationLauncherCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeCurrentAppWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(MTRApplicationLauncherClusterApplicationEP * _Nullable value,
                                                        NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRApplicationLauncherCurrentAppStructAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ApplicationLauncher::Attributes::CurrentApp::TypeInfo;
            auto successFn = Callback<ApplicationLauncherCurrentAppStructAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ApplicationLauncherCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRApplicationLauncherCurrentAppStructAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeCurrentAppWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(MTRApplicationLauncherClusterApplicationEP * _Nullable value,
                                                      NSError * _Nullable error))completionHandler
{
    new MTRApplicationLauncherCurrentAppStructAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ApplicationLauncher::Attributes::CurrentApp::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<ApplicationLauncherCurrentAppStructAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRApplicationLauncherGeneratedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ApplicationLauncher::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<ApplicationLauncherGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ApplicationLauncherCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRApplicationLauncherGeneratedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ApplicationLauncher::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<ApplicationLauncherGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ApplicationLauncherCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRApplicationLauncherGeneratedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRApplicationLauncherGeneratedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ApplicationLauncher::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<ApplicationLauncherGeneratedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRApplicationLauncherAcceptedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ApplicationLauncher::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<ApplicationLauncherAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ApplicationLauncherCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRApplicationLauncherAcceptedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ApplicationLauncher::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<ApplicationLauncherAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ApplicationLauncherCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRApplicationLauncherAcceptedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRApplicationLauncherAcceptedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ApplicationLauncher::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<ApplicationLauncherAcceptedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRApplicationLauncherAttributeListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ApplicationLauncher::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<ApplicationLauncherAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ApplicationLauncherCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRApplicationLauncherAttributeListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ApplicationLauncher::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<ApplicationLauncherAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ApplicationLauncherCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRApplicationLauncherAttributeListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRApplicationLauncherAttributeListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ApplicationLauncher::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<ApplicationLauncherAttributeListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ApplicationLauncher::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ApplicationLauncherCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ApplicationLauncher::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ApplicationLauncherCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ApplicationLauncher::Attributes::FeatureMap::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ApplicationLauncher::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ApplicationLauncherCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ApplicationLauncher::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ApplicationLauncherCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ApplicationLauncher::Attributes::ClusterRevision::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

@end

@implementation MTRBaseClusterApplicationBasic

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = endpoint;
    }
    return self;
}

- (void)readAttributeVendorNameWithCompletionHandler:(void (^)(
                                                         NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ApplicationBasic::Attributes::VendorName::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ApplicationBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeVendorNameWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRCharStringAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ApplicationBasic::Attributes::VendorName::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ApplicationBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRCharStringAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeVendorNameWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ApplicationBasic::Attributes::VendorName::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeVendorIDWithCompletionHandler:(void (^)(
                                                       NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRVendorIdAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ApplicationBasic::Attributes::VendorID::TypeInfo;
            auto successFn = Callback<VendorIdAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ApplicationBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeVendorIDWithMinInterval:(NSNumber * _Nonnull)minInterval
                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                           params:(MTRSubscribeParams * _Nullable)params
                          subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRVendorIdAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ApplicationBasic::Attributes::VendorID::TypeInfo;
            auto successFn = Callback<VendorIdAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ApplicationBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRVendorIdAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeVendorIDWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                       endpoint:(NSNumber *)endpoint
                                          queue:(dispatch_queue_t)queue
                              completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRVendorIdAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ApplicationBasic::Attributes::VendorID::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<VendorIdAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeApplicationNameWithCompletionHandler:(void (^)(NSString * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ApplicationBasic::Attributes::ApplicationName::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ApplicationBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeApplicationNameWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRCharStringAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ApplicationBasic::Attributes::ApplicationName::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ApplicationBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRCharStringAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeApplicationNameWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ApplicationBasic::Attributes::ApplicationName::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeProductIDWithCompletionHandler:(void (^)(
                                                        NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ApplicationBasic::Attributes::ProductID::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ApplicationBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeProductIDWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ApplicationBasic::Attributes::ProductID::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ApplicationBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeProductIDWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ApplicationBasic::Attributes::ProductID::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeApplicationWithCompletionHandler:
    (void (^)(MTRApplicationBasicClusterApplicationBasicApplication * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRApplicationBasicApplicationStructAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ApplicationBasic::Attributes::Application::TypeInfo;
            auto successFn = Callback<ApplicationBasicApplicationStructAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ApplicationBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeApplicationWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:
                                           (void (^)(MTRApplicationBasicClusterApplicationBasicApplication * _Nullable value,
                                               NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRApplicationBasicApplicationStructAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ApplicationBasic::Attributes::Application::TypeInfo;
            auto successFn = Callback<ApplicationBasicApplicationStructAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ApplicationBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRApplicationBasicApplicationStructAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeApplicationWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(MTRApplicationBasicClusterApplicationBasicApplication * _Nullable value,
                                         NSError * _Nullable error))completionHandler
{
    new MTRApplicationBasicApplicationStructAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ApplicationBasic::Attributes::Application::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<ApplicationBasicApplicationStructAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeStatusWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRApplicationBasicClusterApplicationStatusEnumAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ApplicationBasic::Attributes::Status::TypeInfo;
            auto successFn = Callback<ApplicationBasicClusterApplicationStatusEnumAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ApplicationBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeStatusWithMinInterval:(NSNumber * _Nonnull)minInterval
                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                         params:(MTRSubscribeParams * _Nullable)params
                        subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRApplicationBasicClusterApplicationStatusEnumAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ApplicationBasic::Attributes::Status::TypeInfo;
            auto successFn = Callback<ApplicationBasicClusterApplicationStatusEnumAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ApplicationBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRApplicationBasicClusterApplicationStatusEnumAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeStatusWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                     endpoint:(NSNumber *)endpoint
                                        queue:(dispatch_queue_t)queue
                            completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRApplicationBasicClusterApplicationStatusEnumAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ApplicationBasic::Attributes::Status::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<ApplicationBasicClusterApplicationStatusEnumAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeApplicationVersionWithCompletionHandler:(void (^)(NSString * _Nullable value,
                                                                 NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ApplicationBasic::Attributes::ApplicationVersion::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ApplicationBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeApplicationVersionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                maxInterval:(NSNumber * _Nonnull)maxInterval
                                                     params:(MTRSubscribeParams * _Nullable)params
                                    subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                              reportHandler:
                                                  (void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRCharStringAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ApplicationBasic::Attributes::ApplicationVersion::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ApplicationBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRCharStringAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeApplicationVersionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                        completionHandler:
                                            (void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ApplicationBasic::Attributes::ApplicationVersion::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeAllowedVendorListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    new MTRApplicationBasicAllowedVendorListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ApplicationBasic::Attributes::AllowedVendorList::TypeInfo;
            auto successFn = Callback<ApplicationBasicAllowedVendorListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ApplicationBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAllowedVendorListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRApplicationBasicAllowedVendorListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ApplicationBasic::Attributes::AllowedVendorList::TypeInfo;
            auto successFn = Callback<ApplicationBasicAllowedVendorListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ApplicationBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRApplicationBasicAllowedVendorListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAllowedVendorListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRApplicationBasicAllowedVendorListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ApplicationBasic::Attributes::AllowedVendorList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<ApplicationBasicAllowedVendorListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRApplicationBasicGeneratedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ApplicationBasic::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<ApplicationBasicGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ApplicationBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRApplicationBasicGeneratedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ApplicationBasic::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<ApplicationBasicGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ApplicationBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRApplicationBasicGeneratedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRApplicationBasicGeneratedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ApplicationBasic::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<ApplicationBasicGeneratedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRApplicationBasicAcceptedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ApplicationBasic::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<ApplicationBasicAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ApplicationBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRApplicationBasicAcceptedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ApplicationBasic::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<ApplicationBasicAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ApplicationBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRApplicationBasicAcceptedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRApplicationBasicAcceptedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ApplicationBasic::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<ApplicationBasicAcceptedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRApplicationBasicAttributeListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ApplicationBasic::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<ApplicationBasicAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ApplicationBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRApplicationBasicAttributeListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ApplicationBasic::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<ApplicationBasicAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ApplicationBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRApplicationBasicAttributeListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRApplicationBasicAttributeListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ApplicationBasic::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<ApplicationBasicAttributeListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ApplicationBasic::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ApplicationBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ApplicationBasic::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ApplicationBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ApplicationBasic::Attributes::FeatureMap::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ApplicationBasic::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ApplicationBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ApplicationBasic::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ApplicationBasicCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ApplicationBasic::Attributes::ClusterRevision::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

@end

@implementation MTRBaseClusterAccountLogin

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = endpoint;
    }
    return self;
}

- (void)getSetupPINWithParams:(MTRAccountLoginClusterGetSetupPINParams *)params
            completionHandler:(void (^)(MTRAccountLoginClusterGetSetupPINResponseParams * _Nullable data,
                                  NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRAccountLoginClusterGetSetupPINResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            AccountLogin::Commands::GetSetupPIN::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            if (!timedInvokeTimeoutMs.HasValue()) {
                timedInvokeTimeoutMs.SetValue(10000);
            }
            request.tempAccountIdentifier = [self asCharSpan:params.tempAccountIdentifier];

            auto successFn = Callback<AccountLoginClusterGetSetupPINResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::AccountLoginCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)loginWithParams:(MTRAccountLoginClusterLoginParams *)params completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            AccountLogin::Commands::Login::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            if (!timedInvokeTimeoutMs.HasValue()) {
                timedInvokeTimeoutMs.SetValue(10000);
            }
            request.tempAccountIdentifier = [self asCharSpan:params.tempAccountIdentifier];
            request.setupPIN = [self asCharSpan:params.setupPIN];

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::AccountLoginCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)logoutWithCompletionHandler:(StatusCompletion)completionHandler
{
    [self logoutWithParams:nil completionHandler:completionHandler];
}
- (void)logoutWithParams:(MTRAccountLoginClusterLogoutParams * _Nullable)params
       completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            AccountLogin::Commands::Logout::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            if (!timedInvokeTimeoutMs.HasValue()) {
                timedInvokeTimeoutMs.SetValue(10000);
            }

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::AccountLoginCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRAccountLoginGeneratedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = AccountLogin::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<AccountLoginGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::AccountLoginCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRAccountLoginGeneratedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = AccountLogin::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<AccountLoginGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::AccountLoginCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRAccountLoginGeneratedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRAccountLoginGeneratedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = AccountLogin::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<AccountLoginGeneratedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRAccountLoginAcceptedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = AccountLogin::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<AccountLoginAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::AccountLoginCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRAccountLoginAcceptedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = AccountLogin::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<AccountLoginAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::AccountLoginCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRAccountLoginAcceptedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRAccountLoginAcceptedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = AccountLogin::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<AccountLoginAcceptedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRAccountLoginAttributeListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = AccountLogin::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<AccountLoginAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::AccountLoginCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRAccountLoginAttributeListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = AccountLogin::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<AccountLoginAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::AccountLoginCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRAccountLoginAttributeListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRAccountLoginAttributeListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = AccountLogin::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<AccountLoginAttributeListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = AccountLogin::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::AccountLoginCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = AccountLogin::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::AccountLoginCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = AccountLogin::Attributes::FeatureMap::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = AccountLogin::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::AccountLoginCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = AccountLogin::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::AccountLoginCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = AccountLogin::Attributes::ClusterRevision::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

@end

@implementation MTRBaseClusterElectricalMeasurement

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = endpoint;
    }
    return self;
}

- (void)getProfileInfoCommandWithCompletionHandler:(StatusCompletion)completionHandler
{
    [self getProfileInfoCommandWithParams:nil completionHandler:completionHandler];
}
- (void)getProfileInfoCommandWithParams:(MTRElectricalMeasurementClusterGetProfileInfoCommandParams * _Nullable)params
                      completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            ElectricalMeasurement::Commands::GetProfileInfoCommand::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)getMeasurementProfileCommandWithParams:(MTRElectricalMeasurementClusterGetMeasurementProfileCommandParams *)params
                             completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            ElectricalMeasurement::Commands::GetMeasurementProfileCommand::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.attributeId = params.attributeId.unsignedShortValue;
            request.startTime = params.startTime.unsignedIntValue;
            request.numberOfIntervals = params.numberOfIntervals.unsignedCharValue;

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)readAttributeMeasurementTypeWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::MeasurementType::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeMeasurementTypeWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::MeasurementType::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeMeasurementTypeWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::MeasurementType::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeDcVoltageWithCompletionHandler:(void (^)(
                                                        NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::DcVoltage::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeDcVoltageWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::DcVoltage::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeDcVoltageWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::DcVoltage::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeDcVoltageMinWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::DcVoltageMin::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeDcVoltageMinWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::DcVoltageMin::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeDcVoltageMinWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::DcVoltageMin::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeDcVoltageMaxWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::DcVoltageMax::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeDcVoltageMaxWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::DcVoltageMax::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeDcVoltageMaxWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::DcVoltageMax::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeDcCurrentWithCompletionHandler:(void (^)(
                                                        NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::DcCurrent::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeDcCurrentWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::DcCurrent::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeDcCurrentWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::DcCurrent::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeDcCurrentMinWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::DcCurrentMin::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeDcCurrentMinWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::DcCurrentMin::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeDcCurrentMinWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::DcCurrentMin::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeDcCurrentMaxWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::DcCurrentMax::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeDcCurrentMaxWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::DcCurrentMax::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeDcCurrentMaxWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::DcCurrentMax::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeDcPowerWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::DcPower::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeDcPowerWithMinInterval:(NSNumber * _Nonnull)minInterval
                                     maxInterval:(NSNumber * _Nonnull)maxInterval
                                          params:(MTRSubscribeParams * _Nullable)params
                         subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                   reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::DcPower::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeDcPowerWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                      endpoint:(NSNumber *)endpoint
                                         queue:(dispatch_queue_t)queue
                             completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::DcPower::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeDcPowerMinWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::DcPowerMin::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeDcPowerMinWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::DcPowerMin::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeDcPowerMinWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::DcPowerMin::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeDcPowerMaxWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::DcPowerMax::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeDcPowerMaxWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::DcPowerMax::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeDcPowerMaxWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::DcPowerMax::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeDcVoltageMultiplierWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::DcVoltageMultiplier::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeDcVoltageMultiplierWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::DcVoltageMultiplier::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeDcVoltageMultiplierWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::DcVoltageMultiplier::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeDcVoltageDivisorWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::DcVoltageDivisor::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeDcVoltageDivisorWithMinInterval:(NSNumber * _Nonnull)minInterval
                                              maxInterval:(NSNumber * _Nonnull)maxInterval
                                                   params:(MTRSubscribeParams * _Nullable)params
                                  subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                            reportHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::DcVoltageDivisor::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeDcVoltageDivisorWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::DcVoltageDivisor::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeDcCurrentMultiplierWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::DcCurrentMultiplier::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeDcCurrentMultiplierWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::DcCurrentMultiplier::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeDcCurrentMultiplierWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::DcCurrentMultiplier::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeDcCurrentDivisorWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::DcCurrentDivisor::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeDcCurrentDivisorWithMinInterval:(NSNumber * _Nonnull)minInterval
                                              maxInterval:(NSNumber * _Nonnull)maxInterval
                                                   params:(MTRSubscribeParams * _Nullable)params
                                  subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                            reportHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::DcCurrentDivisor::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeDcCurrentDivisorWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::DcCurrentDivisor::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeDcPowerMultiplierWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::DcPowerMultiplier::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeDcPowerMultiplierWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::DcPowerMultiplier::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeDcPowerMultiplierWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::DcPowerMultiplier::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeDcPowerDivisorWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::DcPowerDivisor::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeDcPowerDivisorWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::DcPowerDivisor::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeDcPowerDivisorWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::DcPowerDivisor::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeAcFrequencyWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::AcFrequency::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcFrequencyWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::AcFrequency::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcFrequencyWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::AcFrequency::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeAcFrequencyMinWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::AcFrequencyMin::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcFrequencyMinWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::AcFrequencyMin::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcFrequencyMinWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::AcFrequencyMin::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeAcFrequencyMaxWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::AcFrequencyMax::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcFrequencyMaxWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::AcFrequencyMax::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcFrequencyMaxWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::AcFrequencyMax::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeNeutralCurrentWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::NeutralCurrent::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeNeutralCurrentWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::NeutralCurrent::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeNeutralCurrentWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::NeutralCurrent::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeTotalActivePowerWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    new MTRInt32sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::TotalActivePower::TypeInfo;
            auto successFn = Callback<Int32sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeTotalActivePowerWithMinInterval:(NSNumber * _Nonnull)minInterval
                                              maxInterval:(NSNumber * _Nonnull)maxInterval
                                                   params:(MTRSubscribeParams * _Nullable)params
                                  subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                            reportHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::TotalActivePower::TypeInfo;
            auto successFn = Callback<Int32sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeTotalActivePowerWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::TotalActivePower::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeTotalReactivePowerWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                 NSError * _Nullable error))completionHandler
{
    new MTRInt32sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::TotalReactivePower::TypeInfo;
            auto successFn = Callback<Int32sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeTotalReactivePowerWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                maxInterval:(NSNumber * _Nonnull)maxInterval
                                                     params:(MTRSubscribeParams * _Nullable)params
                                    subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                              reportHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::TotalReactivePower::TypeInfo;
            auto successFn = Callback<Int32sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeTotalReactivePowerWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                        completionHandler:
                                            (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::TotalReactivePower::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeTotalApparentPowerWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                 NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::TotalApparentPower::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeTotalApparentPowerWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                maxInterval:(NSNumber * _Nonnull)maxInterval
                                                     params:(MTRSubscribeParams * _Nullable)params
                                    subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                              reportHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::TotalApparentPower::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeTotalApparentPowerWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                        completionHandler:
                                            (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::TotalApparentPower::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeMeasured1stHarmonicCurrentWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::Measured1stHarmonicCurrent::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeMeasured1stHarmonicCurrentWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                                             params:(MTRSubscribeParams * _Nullable)params
                                            subscriptionEstablished:
                                                (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                      reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::Measured1stHarmonicCurrent::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeMeasured1stHarmonicCurrentWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                         endpoint:(NSNumber *)endpoint
                                                            queue:(dispatch_queue_t)queue
                                                completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::Measured1stHarmonicCurrent::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeMeasured3rdHarmonicCurrentWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::Measured3rdHarmonicCurrent::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeMeasured3rdHarmonicCurrentWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                                             params:(MTRSubscribeParams * _Nullable)params
                                            subscriptionEstablished:
                                                (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                      reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::Measured3rdHarmonicCurrent::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeMeasured3rdHarmonicCurrentWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                         endpoint:(NSNumber *)endpoint
                                                            queue:(dispatch_queue_t)queue
                                                completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::Measured3rdHarmonicCurrent::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeMeasured5thHarmonicCurrentWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::Measured5thHarmonicCurrent::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeMeasured5thHarmonicCurrentWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                                             params:(MTRSubscribeParams * _Nullable)params
                                            subscriptionEstablished:
                                                (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                      reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::Measured5thHarmonicCurrent::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeMeasured5thHarmonicCurrentWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                         endpoint:(NSNumber *)endpoint
                                                            queue:(dispatch_queue_t)queue
                                                completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::Measured5thHarmonicCurrent::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeMeasured7thHarmonicCurrentWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::Measured7thHarmonicCurrent::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeMeasured7thHarmonicCurrentWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                                             params:(MTRSubscribeParams * _Nullable)params
                                            subscriptionEstablished:
                                                (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                      reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::Measured7thHarmonicCurrent::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeMeasured7thHarmonicCurrentWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                         endpoint:(NSNumber *)endpoint
                                                            queue:(dispatch_queue_t)queue
                                                completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::Measured7thHarmonicCurrent::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeMeasured9thHarmonicCurrentWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::Measured9thHarmonicCurrent::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeMeasured9thHarmonicCurrentWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                                             params:(MTRSubscribeParams * _Nullable)params
                                            subscriptionEstablished:
                                                (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                      reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::Measured9thHarmonicCurrent::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeMeasured9thHarmonicCurrentWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                         endpoint:(NSNumber *)endpoint
                                                            queue:(dispatch_queue_t)queue
                                                completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::Measured9thHarmonicCurrent::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeMeasured11thHarmonicCurrentWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                          NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::Measured11thHarmonicCurrent::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeMeasured11thHarmonicCurrentWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                                              params:(MTRSubscribeParams * _Nullable)params
                                             subscriptionEstablished:
                                                 (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                       reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::Measured11thHarmonicCurrent::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeMeasured11thHarmonicCurrentWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                          endpoint:(NSNumber *)endpoint
                                                             queue:(dispatch_queue_t)queue
                                                 completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::Measured11thHarmonicCurrent::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeMeasuredPhase1stHarmonicCurrentWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::MeasuredPhase1stHarmonicCurrent::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeMeasuredPhase1stHarmonicCurrentWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                  params:(MTRSubscribeParams * _Nullable)params
                                                 subscriptionEstablished:
                                                     (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                           reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                             NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::MeasuredPhase1stHarmonicCurrent::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeMeasuredPhase1stHarmonicCurrentWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                              endpoint:(NSNumber *)endpoint
                                                                 queue:(dispatch_queue_t)queue
                                                     completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::MeasuredPhase1stHarmonicCurrent::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeMeasuredPhase3rdHarmonicCurrentWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::MeasuredPhase3rdHarmonicCurrent::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeMeasuredPhase3rdHarmonicCurrentWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                  params:(MTRSubscribeParams * _Nullable)params
                                                 subscriptionEstablished:
                                                     (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                           reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                             NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::MeasuredPhase3rdHarmonicCurrent::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeMeasuredPhase3rdHarmonicCurrentWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                              endpoint:(NSNumber *)endpoint
                                                                 queue:(dispatch_queue_t)queue
                                                     completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::MeasuredPhase3rdHarmonicCurrent::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeMeasuredPhase5thHarmonicCurrentWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::MeasuredPhase5thHarmonicCurrent::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeMeasuredPhase5thHarmonicCurrentWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                  params:(MTRSubscribeParams * _Nullable)params
                                                 subscriptionEstablished:
                                                     (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                           reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                             NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::MeasuredPhase5thHarmonicCurrent::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeMeasuredPhase5thHarmonicCurrentWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                              endpoint:(NSNumber *)endpoint
                                                                 queue:(dispatch_queue_t)queue
                                                     completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::MeasuredPhase5thHarmonicCurrent::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeMeasuredPhase7thHarmonicCurrentWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::MeasuredPhase7thHarmonicCurrent::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeMeasuredPhase7thHarmonicCurrentWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                  params:(MTRSubscribeParams * _Nullable)params
                                                 subscriptionEstablished:
                                                     (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                           reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                             NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::MeasuredPhase7thHarmonicCurrent::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeMeasuredPhase7thHarmonicCurrentWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                              endpoint:(NSNumber *)endpoint
                                                                 queue:(dispatch_queue_t)queue
                                                     completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::MeasuredPhase7thHarmonicCurrent::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeMeasuredPhase9thHarmonicCurrentWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::MeasuredPhase9thHarmonicCurrent::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeMeasuredPhase9thHarmonicCurrentWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                  params:(MTRSubscribeParams * _Nullable)params
                                                 subscriptionEstablished:
                                                     (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                           reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                             NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::MeasuredPhase9thHarmonicCurrent::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeMeasuredPhase9thHarmonicCurrentWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                              endpoint:(NSNumber *)endpoint
                                                                 queue:(dispatch_queue_t)queue
                                                     completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::MeasuredPhase9thHarmonicCurrent::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeMeasuredPhase11thHarmonicCurrentWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                               NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::MeasuredPhase11thHarmonicCurrent::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeMeasuredPhase11thHarmonicCurrentWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                              maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                   params:(MTRSubscribeParams * _Nullable)params
                                                  subscriptionEstablished:
                                                      (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                            reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                              NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::MeasuredPhase11thHarmonicCurrent::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeMeasuredPhase11thHarmonicCurrentWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                               endpoint:(NSNumber *)endpoint
                                                                  queue:(dispatch_queue_t)queue
                                                      completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                            NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::MeasuredPhase11thHarmonicCurrent::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeAcFrequencyMultiplierWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                    NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::AcFrequencyMultiplier::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcFrequencyMultiplierWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                   maxInterval:(NSNumber * _Nonnull)maxInterval
                                                        params:(MTRSubscribeParams * _Nullable)params
                                       subscriptionEstablished:
                                           (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                 reportHandler:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::AcFrequencyMultiplier::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcFrequencyMultiplierWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                           completionHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::AcFrequencyMultiplier::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeAcFrequencyDivisorWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                 NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::AcFrequencyDivisor::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcFrequencyDivisorWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                maxInterval:(NSNumber * _Nonnull)maxInterval
                                                     params:(MTRSubscribeParams * _Nullable)params
                                    subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                              reportHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::AcFrequencyDivisor::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcFrequencyDivisorWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                        completionHandler:
                                            (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::AcFrequencyDivisor::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributePowerMultiplierWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::PowerMultiplier::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributePowerMultiplierWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::PowerMultiplier::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributePowerMultiplierWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::PowerMultiplier::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributePowerDivisorWithCompletionHandler:(void (^)(
                                                           NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::PowerDivisor::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributePowerDivisorWithMinInterval:(NSNumber * _Nonnull)minInterval
                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                               params:(MTRSubscribeParams * _Nullable)params
                              subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                        reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::PowerDivisor::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributePowerDivisorWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                           endpoint:(NSNumber *)endpoint
                                              queue:(dispatch_queue_t)queue
                                  completionHandler:
                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::PowerDivisor::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeHarmonicCurrentMultiplierWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))completionHandler
{
    new MTRInt8sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::HarmonicCurrentMultiplier::TypeInfo;
            auto successFn = Callback<Int8sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeHarmonicCurrentMultiplierWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                                            params:(MTRSubscribeParams * _Nullable)params
                                           subscriptionEstablished:
                                               (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                     reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::HarmonicCurrentMultiplier::TypeInfo;
            auto successFn = Callback<Int8sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeHarmonicCurrentMultiplierWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                        endpoint:(NSNumber *)endpoint
                                                           queue:(dispatch_queue_t)queue
                                               completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completionHandler
{
    new MTRInt8sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::HarmonicCurrentMultiplier::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributePhaseHarmonicCurrentMultiplierWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                             NSError * _Nullable error))completionHandler
{
    new MTRInt8sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::PhaseHarmonicCurrentMultiplier::TypeInfo;
            auto successFn = Callback<Int8sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributePhaseHarmonicCurrentMultiplierWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                 params:(MTRSubscribeParams * _Nullable)params
                                                subscriptionEstablished:
                                                    (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                          reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                            NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::PhaseHarmonicCurrentMultiplier::TypeInfo;
            auto successFn = Callback<Int8sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributePhaseHarmonicCurrentMultiplierWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                             endpoint:(NSNumber *)endpoint
                                                                queue:(dispatch_queue_t)queue
                                                    completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                          NSError * _Nullable error))completionHandler
{
    new MTRInt8sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::PhaseHarmonicCurrentMultiplier::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeInstantaneousVoltageWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::InstantaneousVoltage::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeInstantaneousVoltageWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::InstantaneousVoltage::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeInstantaneousVoltageWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::InstantaneousVoltage::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeInstantaneousLineCurrentWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::InstantaneousLineCurrent::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeInstantaneousLineCurrentWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                                           params:(MTRSubscribeParams * _Nullable)params
                                          subscriptionEstablished:
                                              (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                    reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::InstantaneousLineCurrent::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeInstantaneousLineCurrentWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                       endpoint:(NSNumber *)endpoint
                                                          queue:(dispatch_queue_t)queue
                                              completionHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::InstantaneousLineCurrent::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeInstantaneousActiveCurrentWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::InstantaneousActiveCurrent::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeInstantaneousActiveCurrentWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                                             params:(MTRSubscribeParams * _Nullable)params
                                            subscriptionEstablished:
                                                (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                      reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::InstantaneousActiveCurrent::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeInstantaneousActiveCurrentWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                         endpoint:(NSNumber *)endpoint
                                                            queue:(dispatch_queue_t)queue
                                                completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::InstantaneousActiveCurrent::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeInstantaneousReactiveCurrentWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::InstantaneousReactiveCurrent::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeInstantaneousReactiveCurrentWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                                               params:(MTRSubscribeParams * _Nullable)params
                                              subscriptionEstablished:
                                                  (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                        reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                          NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::InstantaneousReactiveCurrent::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeInstantaneousReactiveCurrentWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                           endpoint:(NSNumber *)endpoint
                                                              queue:(dispatch_queue_t)queue
                                                  completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::InstantaneousReactiveCurrent::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeInstantaneousPowerWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                 NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::InstantaneousPower::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeInstantaneousPowerWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                maxInterval:(NSNumber * _Nonnull)maxInterval
                                                     params:(MTRSubscribeParams * _Nullable)params
                                    subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                              reportHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::InstantaneousPower::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeInstantaneousPowerWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                        completionHandler:
                                            (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::InstantaneousPower::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeRmsVoltageWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltage::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeRmsVoltageWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltage::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeRmsVoltageWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltage::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeRmsVoltageMinWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageMin::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeRmsVoltageMinWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageMin::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeRmsVoltageMinWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageMin::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeRmsVoltageMaxWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageMax::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeRmsVoltageMaxWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageMax::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeRmsVoltageMaxWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageMax::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeRmsCurrentWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::RmsCurrent::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeRmsCurrentWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::RmsCurrent::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeRmsCurrentWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::RmsCurrent::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeRmsCurrentMinWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::RmsCurrentMin::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeRmsCurrentMinWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::RmsCurrentMin::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeRmsCurrentMinWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::RmsCurrentMin::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeRmsCurrentMaxWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::RmsCurrentMax::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeRmsCurrentMaxWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::RmsCurrentMax::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeRmsCurrentMaxWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::RmsCurrentMax::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeActivePowerWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::ActivePower::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeActivePowerWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::ActivePower::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeActivePowerWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::ActivePower::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeActivePowerMinWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::ActivePowerMin::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeActivePowerMinWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::ActivePowerMin::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeActivePowerMinWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::ActivePowerMin::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeActivePowerMaxWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::ActivePowerMax::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeActivePowerMaxWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::ActivePowerMax::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeActivePowerMaxWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::ActivePowerMax::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeReactivePowerWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::ReactivePower::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeReactivePowerWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::ReactivePower::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeReactivePowerWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::ReactivePower::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeApparentPowerWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::ApparentPower::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeApparentPowerWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::ApparentPower::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeApparentPowerWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::ApparentPower::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributePowerFactorWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::PowerFactor::TypeInfo;
            auto successFn = Callback<Int8sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributePowerFactorWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::PowerFactor::TypeInfo;
            auto successFn = Callback<Int8sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributePowerFactorWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::PowerFactor::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeAverageRmsVoltageMeasurementPeriodWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                                 NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::AverageRmsVoltageMeasurementPeriod::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeAverageRmsVoltageMeasurementPeriodWithValue:(NSNumber * _Nonnull)value
                                                completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeAverageRmsVoltageMeasurementPeriodWithValue:(NSNumber * _Nonnull) value
                                                             params:nil
                                                  completionHandler:completionHandler];
}
- (void)writeAttributeAverageRmsVoltageMeasurementPeriodWithValue:(NSNumber * _Nonnull)value
                                                           params:(MTRWriteParams * _Nullable)params
                                                completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = ElectricalMeasurement::Attributes::AverageRmsVoltageMeasurementPeriod::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeAverageRmsVoltageMeasurementPeriodWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                                maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                     params:(MTRSubscribeParams * _Nullable)params
                                                    subscriptionEstablished:
                                                        (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                              reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                                NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::AverageRmsVoltageMeasurementPeriod::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAverageRmsVoltageMeasurementPeriodWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                                 endpoint:(NSNumber *)endpoint
                                                                    queue:(dispatch_queue_t)queue
                                                        completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::AverageRmsVoltageMeasurementPeriod::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeAverageRmsUnderVoltageCounterWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                            NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::AverageRmsUnderVoltageCounter::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeAverageRmsUnderVoltageCounterWithValue:(NSNumber * _Nonnull)value
                                           completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeAverageRmsUnderVoltageCounterWithValue:(NSNumber * _Nonnull) value
                                                        params:nil
                                             completionHandler:completionHandler];
}
- (void)writeAttributeAverageRmsUnderVoltageCounterWithValue:(NSNumber * _Nonnull)value
                                                      params:(MTRWriteParams * _Nullable)params
                                           completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = ElectricalMeasurement::Attributes::AverageRmsUnderVoltageCounter::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeAverageRmsUnderVoltageCounterWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                params:(MTRSubscribeParams * _Nullable)params
                                               subscriptionEstablished:
                                                   (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                         reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::AverageRmsUnderVoltageCounter::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAverageRmsUnderVoltageCounterWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                            endpoint:(NSNumber *)endpoint
                                                               queue:(dispatch_queue_t)queue
                                                   completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::AverageRmsUnderVoltageCounter::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeRmsExtremeOverVoltagePeriodWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                          NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::RmsExtremeOverVoltagePeriod::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeRmsExtremeOverVoltagePeriodWithValue:(NSNumber * _Nonnull)value
                                         completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeRmsExtremeOverVoltagePeriodWithValue:(NSNumber * _Nonnull) value
                                                      params:nil
                                           completionHandler:completionHandler];
}
- (void)writeAttributeRmsExtremeOverVoltagePeriodWithValue:(NSNumber * _Nonnull)value
                                                    params:(MTRWriteParams * _Nullable)params
                                         completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = ElectricalMeasurement::Attributes::RmsExtremeOverVoltagePeriod::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeRmsExtremeOverVoltagePeriodWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                                              params:(MTRSubscribeParams * _Nullable)params
                                             subscriptionEstablished:
                                                 (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                       reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::RmsExtremeOverVoltagePeriod::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeRmsExtremeOverVoltagePeriodWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                          endpoint:(NSNumber *)endpoint
                                                             queue:(dispatch_queue_t)queue
                                                 completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::RmsExtremeOverVoltagePeriod::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeRmsExtremeUnderVoltagePeriodWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::RmsExtremeUnderVoltagePeriod::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeRmsExtremeUnderVoltagePeriodWithValue:(NSNumber * _Nonnull)value
                                          completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeRmsExtremeUnderVoltagePeriodWithValue:(NSNumber * _Nonnull) value
                                                       params:nil
                                            completionHandler:completionHandler];
}
- (void)writeAttributeRmsExtremeUnderVoltagePeriodWithValue:(NSNumber * _Nonnull)value
                                                     params:(MTRWriteParams * _Nullable)params
                                          completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = ElectricalMeasurement::Attributes::RmsExtremeUnderVoltagePeriod::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeRmsExtremeUnderVoltagePeriodWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                                               params:(MTRSubscribeParams * _Nullable)params
                                              subscriptionEstablished:
                                                  (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                        reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                          NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::RmsExtremeUnderVoltagePeriod::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeRmsExtremeUnderVoltagePeriodWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                           endpoint:(NSNumber *)endpoint
                                                              queue:(dispatch_queue_t)queue
                                                  completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::RmsExtremeUnderVoltagePeriod::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeRmsVoltageSagPeriodWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageSagPeriod::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeRmsVoltageSagPeriodWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeRmsVoltageSagPeriodWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeRmsVoltageSagPeriodWithValue:(NSNumber * _Nonnull)value
                                            params:(MTRWriteParams * _Nullable)params
                                 completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageSagPeriod::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeRmsVoltageSagPeriodWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageSagPeriod::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeRmsVoltageSagPeriodWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageSagPeriod::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeRmsVoltageSwellPeriodWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                    NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageSwellPeriod::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeRmsVoltageSwellPeriodWithValue:(NSNumber * _Nonnull)value
                                   completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeRmsVoltageSwellPeriodWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeRmsVoltageSwellPeriodWithValue:(NSNumber * _Nonnull)value
                                              params:(MTRWriteParams * _Nullable)params
                                   completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageSwellPeriod::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeRmsVoltageSwellPeriodWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                   maxInterval:(NSNumber * _Nonnull)maxInterval
                                                        params:(MTRSubscribeParams * _Nullable)params
                                       subscriptionEstablished:
                                           (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                 reportHandler:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageSwellPeriod::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeRmsVoltageSwellPeriodWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                           completionHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageSwellPeriod::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeAcVoltageMultiplierWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::AcVoltageMultiplier::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcVoltageMultiplierWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::AcVoltageMultiplier::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcVoltageMultiplierWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::AcVoltageMultiplier::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeAcVoltageDivisorWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::AcVoltageDivisor::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcVoltageDivisorWithMinInterval:(NSNumber * _Nonnull)minInterval
                                              maxInterval:(NSNumber * _Nonnull)maxInterval
                                                   params:(MTRSubscribeParams * _Nullable)params
                                  subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                            reportHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::AcVoltageDivisor::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcVoltageDivisorWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::AcVoltageDivisor::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeAcCurrentMultiplierWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::AcCurrentMultiplier::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcCurrentMultiplierWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::AcCurrentMultiplier::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcCurrentMultiplierWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::AcCurrentMultiplier::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeAcCurrentDivisorWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::AcCurrentDivisor::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcCurrentDivisorWithMinInterval:(NSNumber * _Nonnull)minInterval
                                              maxInterval:(NSNumber * _Nonnull)maxInterval
                                                   params:(MTRSubscribeParams * _Nullable)params
                                  subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                            reportHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::AcCurrentDivisor::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcCurrentDivisorWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::AcCurrentDivisor::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeAcPowerMultiplierWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::AcPowerMultiplier::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcPowerMultiplierWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::AcPowerMultiplier::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcPowerMultiplierWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::AcPowerMultiplier::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeAcPowerDivisorWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::AcPowerDivisor::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcPowerDivisorWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::AcPowerDivisor::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcPowerDivisorWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::AcPowerDivisor::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeOverloadAlarmsMaskWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                 NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::OverloadAlarmsMask::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeOverloadAlarmsMaskWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeOverloadAlarmsMaskWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeOverloadAlarmsMaskWithValue:(NSNumber * _Nonnull)value
                                           params:(MTRWriteParams * _Nullable)params
                                completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = ElectricalMeasurement::Attributes::OverloadAlarmsMask::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedCharValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeOverloadAlarmsMaskWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                maxInterval:(NSNumber * _Nonnull)maxInterval
                                                     params:(MTRSubscribeParams * _Nullable)params
                                    subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                              reportHandler:
                                                  (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::OverloadAlarmsMask::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeOverloadAlarmsMaskWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                        completionHandler:
                                            (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::OverloadAlarmsMask::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeVoltageOverloadWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::VoltageOverload::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeVoltageOverloadWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::VoltageOverload::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeVoltageOverloadWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::VoltageOverload::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeCurrentOverloadWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::CurrentOverload::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeCurrentOverloadWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::CurrentOverload::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeCurrentOverloadWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::CurrentOverload::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeAcOverloadAlarmsMaskWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::AcOverloadAlarmsMask::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeAcOverloadAlarmsMaskWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeAcOverloadAlarmsMaskWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeAcOverloadAlarmsMaskWithValue:(NSNumber * _Nonnull)value
                                             params:(MTRWriteParams * _Nullable)params
                                  completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = ElectricalMeasurement::Attributes::AcOverloadAlarmsMask::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeAcOverloadAlarmsMaskWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::AcOverloadAlarmsMask::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcOverloadAlarmsMaskWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::AcOverloadAlarmsMask::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeAcVoltageOverloadWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::AcVoltageOverload::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcVoltageOverloadWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::AcVoltageOverload::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcVoltageOverloadWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::AcVoltageOverload::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeAcCurrentOverloadWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::AcCurrentOverload::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcCurrentOverloadWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::AcCurrentOverload::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcCurrentOverloadWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::AcCurrentOverload::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeAcActivePowerOverloadWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                    NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::AcActivePowerOverload::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcActivePowerOverloadWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                   maxInterval:(NSNumber * _Nonnull)maxInterval
                                                        params:(MTRSubscribeParams * _Nullable)params
                                       subscriptionEstablished:
                                           (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                 reportHandler:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::AcActivePowerOverload::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcActivePowerOverloadWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                           completionHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::AcActivePowerOverload::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeAcReactivePowerOverloadWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                      NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::AcReactivePowerOverload::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcReactivePowerOverloadWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                     maxInterval:(NSNumber * _Nonnull)maxInterval
                                                          params:(MTRSubscribeParams * _Nullable)params
                                         subscriptionEstablished:
                                             (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                   reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::AcReactivePowerOverload::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcReactivePowerOverloadWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                      endpoint:(NSNumber *)endpoint
                                                         queue:(dispatch_queue_t)queue
                                             completionHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::AcReactivePowerOverload::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeAverageRmsOverVoltageWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                    NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::AverageRmsOverVoltage::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAverageRmsOverVoltageWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                   maxInterval:(NSNumber * _Nonnull)maxInterval
                                                        params:(MTRSubscribeParams * _Nullable)params
                                       subscriptionEstablished:
                                           (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                 reportHandler:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::AverageRmsOverVoltage::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAverageRmsOverVoltageWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                           completionHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::AverageRmsOverVoltage::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeAverageRmsUnderVoltageWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::AverageRmsUnderVoltage::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAverageRmsUnderVoltageWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                                         params:(MTRSubscribeParams * _Nullable)params
                                        subscriptionEstablished:
                                            (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                  reportHandler:
                                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::AverageRmsUnderVoltage::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAverageRmsUnderVoltageWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                            completionHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::AverageRmsUnderVoltage::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeRmsExtremeOverVoltageWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                    NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::RmsExtremeOverVoltage::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeRmsExtremeOverVoltageWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                   maxInterval:(NSNumber * _Nonnull)maxInterval
                                                        params:(MTRSubscribeParams * _Nullable)params
                                       subscriptionEstablished:
                                           (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                 reportHandler:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::RmsExtremeOverVoltage::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeRmsExtremeOverVoltageWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                           completionHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::RmsExtremeOverVoltage::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeRmsExtremeUnderVoltageWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::RmsExtremeUnderVoltage::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeRmsExtremeUnderVoltageWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                                         params:(MTRSubscribeParams * _Nullable)params
                                        subscriptionEstablished:
                                            (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                  reportHandler:
                                                      (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::RmsExtremeUnderVoltage::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeRmsExtremeUnderVoltageWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                     endpoint:(NSNumber *)endpoint
                                                        queue:(dispatch_queue_t)queue
                                            completionHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::RmsExtremeUnderVoltage::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeRmsVoltageSagWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageSag::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeRmsVoltageSagWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageSag::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeRmsVoltageSagWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageSag::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeRmsVoltageSwellWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageSwell::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeRmsVoltageSwellWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageSwell::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeRmsVoltageSwellWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageSwell::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeLineCurrentPhaseBWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::LineCurrentPhaseB::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeLineCurrentPhaseBWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::LineCurrentPhaseB::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeLineCurrentPhaseBWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::LineCurrentPhaseB::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeActiveCurrentPhaseBWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::ActiveCurrentPhaseB::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeActiveCurrentPhaseBWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::ActiveCurrentPhaseB::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeActiveCurrentPhaseBWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::ActiveCurrentPhaseB::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeReactiveCurrentPhaseBWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                    NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::ReactiveCurrentPhaseB::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeReactiveCurrentPhaseBWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                   maxInterval:(NSNumber * _Nonnull)maxInterval
                                                        params:(MTRSubscribeParams * _Nullable)params
                                       subscriptionEstablished:
                                           (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                 reportHandler:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::ReactiveCurrentPhaseB::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeReactiveCurrentPhaseBWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                           completionHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::ReactiveCurrentPhaseB::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeRmsVoltagePhaseBWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltagePhaseB::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeRmsVoltagePhaseBWithMinInterval:(NSNumber * _Nonnull)minInterval
                                              maxInterval:(NSNumber * _Nonnull)maxInterval
                                                   params:(MTRSubscribeParams * _Nullable)params
                                  subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                            reportHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltagePhaseB::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeRmsVoltagePhaseBWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltagePhaseB::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeRmsVoltageMinPhaseBWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageMinPhaseB::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeRmsVoltageMinPhaseBWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageMinPhaseB::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeRmsVoltageMinPhaseBWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageMinPhaseB::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeRmsVoltageMaxPhaseBWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageMaxPhaseB::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeRmsVoltageMaxPhaseBWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageMaxPhaseB::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeRmsVoltageMaxPhaseBWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageMaxPhaseB::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeRmsCurrentPhaseBWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::RmsCurrentPhaseB::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeRmsCurrentPhaseBWithMinInterval:(NSNumber * _Nonnull)minInterval
                                              maxInterval:(NSNumber * _Nonnull)maxInterval
                                                   params:(MTRSubscribeParams * _Nullable)params
                                  subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                            reportHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::RmsCurrentPhaseB::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeRmsCurrentPhaseBWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::RmsCurrentPhaseB::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeRmsCurrentMinPhaseBWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::RmsCurrentMinPhaseB::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeRmsCurrentMinPhaseBWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::RmsCurrentMinPhaseB::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeRmsCurrentMinPhaseBWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::RmsCurrentMinPhaseB::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeRmsCurrentMaxPhaseBWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::RmsCurrentMaxPhaseB::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeRmsCurrentMaxPhaseBWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::RmsCurrentMaxPhaseB::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeRmsCurrentMaxPhaseBWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::RmsCurrentMaxPhaseB::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeActivePowerPhaseBWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::ActivePowerPhaseB::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeActivePowerPhaseBWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::ActivePowerPhaseB::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeActivePowerPhaseBWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::ActivePowerPhaseB::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeActivePowerMinPhaseBWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::ActivePowerMinPhaseB::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeActivePowerMinPhaseBWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::ActivePowerMinPhaseB::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeActivePowerMinPhaseBWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::ActivePowerMinPhaseB::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeActivePowerMaxPhaseBWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::ActivePowerMaxPhaseB::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeActivePowerMaxPhaseBWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::ActivePowerMaxPhaseB::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeActivePowerMaxPhaseBWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::ActivePowerMaxPhaseB::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeReactivePowerPhaseBWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::ReactivePowerPhaseB::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeReactivePowerPhaseBWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::ReactivePowerPhaseB::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeReactivePowerPhaseBWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::ReactivePowerPhaseB::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeApparentPowerPhaseBWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::ApparentPowerPhaseB::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeApparentPowerPhaseBWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::ApparentPowerPhaseB::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeApparentPowerPhaseBWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::ApparentPowerPhaseB::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributePowerFactorPhaseBWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    new MTRInt8sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::PowerFactorPhaseB::TypeInfo;
            auto successFn = Callback<Int8sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributePowerFactorPhaseBWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::PowerFactorPhaseB::TypeInfo;
            auto successFn = Callback<Int8sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributePowerFactorPhaseBWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::PowerFactorPhaseB::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeAverageRmsVoltageMeasurementPeriodPhaseBWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                                       NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::AverageRmsVoltageMeasurementPeriodPhaseB::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAverageRmsVoltageMeasurementPeriodPhaseBWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                           params:(MTRSubscribeParams * _Nullable)params
                                                          subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)
                                                                                      subscriptionEstablishedHandler
                                                                    reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                                      NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::AverageRmsVoltageMeasurementPeriodPhaseB::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAverageRmsVoltageMeasurementPeriodPhaseBWithAttributeCache:
            (MTRAttributeCacheContainer *)attributeCacheContainer
                                                                       endpoint:(NSNumber *)endpoint
                                                                          queue:(dispatch_queue_t)queue
                                                              completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                                    NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::AverageRmsVoltageMeasurementPeriodPhaseB::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeAverageRmsOverVoltageCounterPhaseBWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                                 NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::AverageRmsOverVoltageCounterPhaseB::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAverageRmsOverVoltageCounterPhaseBWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                                maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                     params:(MTRSubscribeParams * _Nullable)params
                                                    subscriptionEstablished:
                                                        (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                              reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                                NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::AverageRmsOverVoltageCounterPhaseB::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAverageRmsOverVoltageCounterPhaseBWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                                 endpoint:(NSNumber *)endpoint
                                                                    queue:(dispatch_queue_t)queue
                                                        completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::AverageRmsOverVoltageCounterPhaseB::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeAverageRmsUnderVoltageCounterPhaseBWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                                  NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::AverageRmsUnderVoltageCounterPhaseB::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAverageRmsUnderVoltageCounterPhaseBWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                      params:(MTRSubscribeParams * _Nullable)params
                                                     subscriptionEstablished:
                                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                               reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                                 NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::AverageRmsUnderVoltageCounterPhaseB::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAverageRmsUnderVoltageCounterPhaseBWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                                  endpoint:(NSNumber *)endpoint
                                                                     queue:(dispatch_queue_t)queue
                                                         completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                               NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::AverageRmsUnderVoltageCounterPhaseB::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeRmsExtremeOverVoltagePeriodPhaseBWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                                NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::RmsExtremeOverVoltagePeriodPhaseB::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeRmsExtremeOverVoltagePeriodPhaseBWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                    params:(MTRSubscribeParams * _Nullable)params
                                                   subscriptionEstablished:
                                                       (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                             reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                               NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::RmsExtremeOverVoltagePeriodPhaseB::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeRmsExtremeOverVoltagePeriodPhaseBWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                                endpoint:(NSNumber *)endpoint
                                                                   queue:(dispatch_queue_t)queue
                                                       completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                             NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::RmsExtremeOverVoltagePeriodPhaseB::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeRmsExtremeUnderVoltagePeriodPhaseBWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                                 NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::RmsExtremeUnderVoltagePeriodPhaseB::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeRmsExtremeUnderVoltagePeriodPhaseBWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                                maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                     params:(MTRSubscribeParams * _Nullable)params
                                                    subscriptionEstablished:
                                                        (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                              reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                                NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::RmsExtremeUnderVoltagePeriodPhaseB::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeRmsExtremeUnderVoltagePeriodPhaseBWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                                 endpoint:(NSNumber *)endpoint
                                                                    queue:(dispatch_queue_t)queue
                                                        completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::RmsExtremeUnderVoltagePeriodPhaseB::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeRmsVoltageSagPeriodPhaseBWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageSagPeriodPhaseB::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeRmsVoltageSagPeriodPhaseBWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                                            params:(MTRSubscribeParams * _Nullable)params
                                           subscriptionEstablished:
                                               (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                     reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageSagPeriodPhaseB::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeRmsVoltageSagPeriodPhaseBWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                        endpoint:(NSNumber *)endpoint
                                                           queue:(dispatch_queue_t)queue
                                               completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageSagPeriodPhaseB::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeRmsVoltageSwellPeriodPhaseBWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                          NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageSwellPeriodPhaseB::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeRmsVoltageSwellPeriodPhaseBWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                                              params:(MTRSubscribeParams * _Nullable)params
                                             subscriptionEstablished:
                                                 (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                       reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageSwellPeriodPhaseB::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeRmsVoltageSwellPeriodPhaseBWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                          endpoint:(NSNumber *)endpoint
                                                             queue:(dispatch_queue_t)queue
                                                 completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageSwellPeriodPhaseB::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeLineCurrentPhaseCWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::LineCurrentPhaseC::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeLineCurrentPhaseCWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::LineCurrentPhaseC::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeLineCurrentPhaseCWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::LineCurrentPhaseC::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeActiveCurrentPhaseCWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::ActiveCurrentPhaseC::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeActiveCurrentPhaseCWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::ActiveCurrentPhaseC::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeActiveCurrentPhaseCWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::ActiveCurrentPhaseC::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeReactiveCurrentPhaseCWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                    NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::ReactiveCurrentPhaseC::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeReactiveCurrentPhaseCWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                   maxInterval:(NSNumber * _Nonnull)maxInterval
                                                        params:(MTRSubscribeParams * _Nullable)params
                                       subscriptionEstablished:
                                           (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                 reportHandler:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::ReactiveCurrentPhaseC::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeReactiveCurrentPhaseCWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                           completionHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::ReactiveCurrentPhaseC::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeRmsVoltagePhaseCWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltagePhaseC::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeRmsVoltagePhaseCWithMinInterval:(NSNumber * _Nonnull)minInterval
                                              maxInterval:(NSNumber * _Nonnull)maxInterval
                                                   params:(MTRSubscribeParams * _Nullable)params
                                  subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                            reportHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltagePhaseC::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeRmsVoltagePhaseCWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltagePhaseC::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeRmsVoltageMinPhaseCWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageMinPhaseC::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeRmsVoltageMinPhaseCWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageMinPhaseC::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeRmsVoltageMinPhaseCWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageMinPhaseC::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeRmsVoltageMaxPhaseCWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageMaxPhaseC::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeRmsVoltageMaxPhaseCWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageMaxPhaseC::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeRmsVoltageMaxPhaseCWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageMaxPhaseC::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeRmsCurrentPhaseCWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::RmsCurrentPhaseC::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeRmsCurrentPhaseCWithMinInterval:(NSNumber * _Nonnull)minInterval
                                              maxInterval:(NSNumber * _Nonnull)maxInterval
                                                   params:(MTRSubscribeParams * _Nullable)params
                                  subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                            reportHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::RmsCurrentPhaseC::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeRmsCurrentPhaseCWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::RmsCurrentPhaseC::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeRmsCurrentMinPhaseCWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::RmsCurrentMinPhaseC::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeRmsCurrentMinPhaseCWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::RmsCurrentMinPhaseC::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeRmsCurrentMinPhaseCWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::RmsCurrentMinPhaseC::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeRmsCurrentMaxPhaseCWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::RmsCurrentMaxPhaseC::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeRmsCurrentMaxPhaseCWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::RmsCurrentMaxPhaseC::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeRmsCurrentMaxPhaseCWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::RmsCurrentMaxPhaseC::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeActivePowerPhaseCWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::ActivePowerPhaseC::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeActivePowerPhaseCWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::ActivePowerPhaseC::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeActivePowerPhaseCWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::ActivePowerPhaseC::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeActivePowerMinPhaseCWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::ActivePowerMinPhaseC::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeActivePowerMinPhaseCWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::ActivePowerMinPhaseC::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeActivePowerMinPhaseCWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::ActivePowerMinPhaseC::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeActivePowerMaxPhaseCWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::ActivePowerMaxPhaseC::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeActivePowerMaxPhaseCWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::ActivePowerMaxPhaseC::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeActivePowerMaxPhaseCWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::ActivePowerMaxPhaseC::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeReactivePowerPhaseCWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::ReactivePowerPhaseC::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeReactivePowerPhaseCWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::ReactivePowerPhaseC::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeReactivePowerPhaseCWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::ReactivePowerPhaseC::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeApparentPowerPhaseCWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::ApparentPowerPhaseC::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeApparentPowerPhaseCWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::ApparentPowerPhaseC::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeApparentPowerPhaseCWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::ApparentPowerPhaseC::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributePowerFactorPhaseCWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    new MTRInt8sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::PowerFactorPhaseC::TypeInfo;
            auto successFn = Callback<Int8sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributePowerFactorPhaseCWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::PowerFactorPhaseC::TypeInfo;
            auto successFn = Callback<Int8sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributePowerFactorPhaseCWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::PowerFactorPhaseC::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeAverageRmsVoltageMeasurementPeriodPhaseCWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                                       NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::AverageRmsVoltageMeasurementPeriodPhaseC::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAverageRmsVoltageMeasurementPeriodPhaseCWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                           params:(MTRSubscribeParams * _Nullable)params
                                                          subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)
                                                                                      subscriptionEstablishedHandler
                                                                    reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                                      NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::AverageRmsVoltageMeasurementPeriodPhaseC::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAverageRmsVoltageMeasurementPeriodPhaseCWithAttributeCache:
            (MTRAttributeCacheContainer *)attributeCacheContainer
                                                                       endpoint:(NSNumber *)endpoint
                                                                          queue:(dispatch_queue_t)queue
                                                              completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                                    NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::AverageRmsVoltageMeasurementPeriodPhaseC::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeAverageRmsOverVoltageCounterPhaseCWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                                 NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::AverageRmsOverVoltageCounterPhaseC::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAverageRmsOverVoltageCounterPhaseCWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                                maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                     params:(MTRSubscribeParams * _Nullable)params
                                                    subscriptionEstablished:
                                                        (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                              reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                                NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::AverageRmsOverVoltageCounterPhaseC::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAverageRmsOverVoltageCounterPhaseCWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                                 endpoint:(NSNumber *)endpoint
                                                                    queue:(dispatch_queue_t)queue
                                                        completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::AverageRmsOverVoltageCounterPhaseC::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeAverageRmsUnderVoltageCounterPhaseCWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                                  NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::AverageRmsUnderVoltageCounterPhaseC::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAverageRmsUnderVoltageCounterPhaseCWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                      params:(MTRSubscribeParams * _Nullable)params
                                                     subscriptionEstablished:
                                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                               reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                                 NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::AverageRmsUnderVoltageCounterPhaseC::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAverageRmsUnderVoltageCounterPhaseCWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                                  endpoint:(NSNumber *)endpoint
                                                                     queue:(dispatch_queue_t)queue
                                                         completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                               NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::AverageRmsUnderVoltageCounterPhaseC::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeRmsExtremeOverVoltagePeriodPhaseCWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                                NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::RmsExtremeOverVoltagePeriodPhaseC::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeRmsExtremeOverVoltagePeriodPhaseCWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                    params:(MTRSubscribeParams * _Nullable)params
                                                   subscriptionEstablished:
                                                       (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                             reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                               NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::RmsExtremeOverVoltagePeriodPhaseC::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeRmsExtremeOverVoltagePeriodPhaseCWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                                endpoint:(NSNumber *)endpoint
                                                                   queue:(dispatch_queue_t)queue
                                                       completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                             NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::RmsExtremeOverVoltagePeriodPhaseC::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeRmsExtremeUnderVoltagePeriodPhaseCWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                                 NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::RmsExtremeUnderVoltagePeriodPhaseC::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeRmsExtremeUnderVoltagePeriodPhaseCWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                                maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                     params:(MTRSubscribeParams * _Nullable)params
                                                    subscriptionEstablished:
                                                        (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                              reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                                NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::RmsExtremeUnderVoltagePeriodPhaseC::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeRmsExtremeUnderVoltagePeriodPhaseCWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                                 endpoint:(NSNumber *)endpoint
                                                                    queue:(dispatch_queue_t)queue
                                                        completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::RmsExtremeUnderVoltagePeriodPhaseC::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeRmsVoltageSagPeriodPhaseCWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageSagPeriodPhaseC::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeRmsVoltageSagPeriodPhaseCWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                                            params:(MTRSubscribeParams * _Nullable)params
                                           subscriptionEstablished:
                                               (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                     reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageSagPeriodPhaseC::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeRmsVoltageSagPeriodPhaseCWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                        endpoint:(NSNumber *)endpoint
                                                           queue:(dispatch_queue_t)queue
                                               completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                     NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageSagPeriodPhaseC::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeRmsVoltageSwellPeriodPhaseCWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                          NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageSwellPeriodPhaseC::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeRmsVoltageSwellPeriodPhaseCWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                                              params:(MTRSubscribeParams * _Nullable)params
                                             subscriptionEstablished:
                                                 (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                       reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageSwellPeriodPhaseC::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeRmsVoltageSwellPeriodPhaseCWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                          endpoint:(NSNumber *)endpoint
                                                             queue:(dispatch_queue_t)queue
                                                 completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                       NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::RmsVoltageSwellPeriodPhaseC::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRElectricalMeasurementGeneratedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<ElectricalMeasurementGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRElectricalMeasurementGeneratedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<ElectricalMeasurementGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRElectricalMeasurementGeneratedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRElectricalMeasurementGeneratedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<ElectricalMeasurementGeneratedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRElectricalMeasurementAcceptedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<ElectricalMeasurementAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRElectricalMeasurementAcceptedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<ElectricalMeasurementAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRElectricalMeasurementAcceptedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRElectricalMeasurementAcceptedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<ElectricalMeasurementAcceptedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRElectricalMeasurementAttributeListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<ElectricalMeasurementAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRElectricalMeasurementAttributeListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<ElectricalMeasurementAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRElectricalMeasurementAttributeListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRElectricalMeasurementAttributeListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = ElectricalMeasurement::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<ElectricalMeasurementAttributeListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::FeatureMap::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = ElectricalMeasurement::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = ElectricalMeasurement::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::ElectricalMeasurementCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = ElectricalMeasurement::Attributes::ClusterRevision::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

@end

@implementation MTRBaseClusterTestCluster

- (instancetype)initWithDevice:(MTRBaseDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        _device = device;
        _endpoint = endpoint;
    }
    return self;
}

- (void)testWithCompletionHandler:(StatusCompletion)completionHandler
{
    [self testWithParams:nil completionHandler:completionHandler];
}
- (void)testWithParams:(MTRTestClusterClusterTestParams * _Nullable)params completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            TestCluster::Commands::Test::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)testNotHandledWithCompletionHandler:(StatusCompletion)completionHandler
{
    [self testNotHandledWithParams:nil completionHandler:completionHandler];
}
- (void)testNotHandledWithParams:(MTRTestClusterClusterTestNotHandledParams * _Nullable)params
               completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            TestCluster::Commands::TestNotHandled::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)testSpecificWithCompletionHandler:(void (^)(MTRTestClusterClusterTestSpecificResponseParams * _Nullable data,
                                              NSError * _Nullable error))completionHandler
{
    [self testSpecificWithParams:nil completionHandler:completionHandler];
}
- (void)testSpecificWithParams:(MTRTestClusterClusterTestSpecificParams * _Nullable)params
             completionHandler:(void (^)(MTRTestClusterClusterTestSpecificResponseParams * _Nullable data,
                                   NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRTestClusterClusterTestSpecificResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            TestCluster::Commands::TestSpecific::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }

            auto successFn = Callback<TestClusterClusterTestSpecificResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)testUnknownCommandWithCompletionHandler:(StatusCompletion)completionHandler
{
    [self testUnknownCommandWithParams:nil completionHandler:completionHandler];
}
- (void)testUnknownCommandWithParams:(MTRTestClusterClusterTestUnknownCommandParams * _Nullable)params
                   completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            TestCluster::Commands::TestUnknownCommand::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)testAddArgumentsWithParams:(MTRTestClusterClusterTestAddArgumentsParams *)params
                 completionHandler:(void (^)(MTRTestClusterClusterTestAddArgumentsResponseParams * _Nullable data,
                                       NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRTestClusterClusterTestAddArgumentsResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            TestCluster::Commands::TestAddArguments::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.arg1 = params.arg1.unsignedCharValue;
            request.arg2 = params.arg2.unsignedCharValue;

            auto successFn = Callback<TestClusterClusterTestAddArgumentsResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)testSimpleArgumentRequestWithParams:(MTRTestClusterClusterTestSimpleArgumentRequestParams *)params
                          completionHandler:(void (^)(MTRTestClusterClusterTestSimpleArgumentResponseParams * _Nullable data,
                                                NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRTestClusterClusterTestSimpleArgumentResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            TestCluster::Commands::TestSimpleArgumentRequest::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.arg1 = params.arg1.boolValue;

            auto successFn = Callback<TestClusterClusterTestSimpleArgumentResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)testStructArrayArgumentRequestWithParams:(MTRTestClusterClusterTestStructArrayArgumentRequestParams *)params
                               completionHandler:
                                   (void (^)(MTRTestClusterClusterTestStructArrayArgumentResponseParams * _Nullable data,
                                       NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRTestClusterClusterTestStructArrayArgumentResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            TestCluster::Commands::TestStructArrayArgumentRequest::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            {
                using ListType_0 = std::remove_reference_t<decltype(request.arg1)>;
                using ListMemberType_0 = ListMemberTypeGetter<ListType_0>::Type;
                if (params.arg1.count != 0) {
                    auto * listHolder_0 = new ListHolder<ListMemberType_0>(params.arg1.count);
                    if (listHolder_0 == nullptr || listHolder_0->mList == nullptr) {
                        return CHIP_ERROR_INVALID_ARGUMENT;
                    }
                    listFreer.add(listHolder_0);
                    for (size_t i_0 = 0; i_0 < params.arg1.count; ++i_0) {
                        if (![params.arg1[i_0] isKindOfClass:[MTRTestClusterClusterNestedStructList class]]) {
                            // Wrong kind of value.
                            return CHIP_ERROR_INVALID_ARGUMENT;
                        }
                        auto element_0 = (MTRTestClusterClusterNestedStructList *) params.arg1[i_0];
                        listHolder_0->mList[i_0].a = element_0.a.unsignedCharValue;
                        listHolder_0->mList[i_0].b = element_0.b.boolValue;
                        listHolder_0->mList[i_0].c.a = element_0.c.a.unsignedCharValue;
                        listHolder_0->mList[i_0].c.b = element_0.c.b.boolValue;
                        listHolder_0->mList[i_0].c.c = static_cast<std::remove_reference_t<decltype(listHolder_0->mList[i_0].c.c)>>(
                            element_0.c.c.unsignedCharValue);
                        listHolder_0->mList[i_0].c.d = [self asByteSpan:element_0.c.d];
                        listHolder_0->mList[i_0].c.e = [self asCharSpan:element_0.c.e];
                        listHolder_0->mList[i_0].c.f = static_cast<std::remove_reference_t<decltype(listHolder_0->mList[i_0].c.f)>>(
                            element_0.c.f.unsignedCharValue);
                        listHolder_0->mList[i_0].c.g = element_0.c.g.floatValue;
                        listHolder_0->mList[i_0].c.h = element_0.c.h.doubleValue;
                        {
                            using ListType_2 = std::remove_reference_t<decltype(listHolder_0->mList[i_0].d)>;
                            using ListMemberType_2 = ListMemberTypeGetter<ListType_2>::Type;
                            if (element_0.d.count != 0) {
                                auto * listHolder_2 = new ListHolder<ListMemberType_2>(element_0.d.count);
                                if (listHolder_2 == nullptr || listHolder_2->mList == nullptr) {
                                    return CHIP_ERROR_INVALID_ARGUMENT;
                                }
                                listFreer.add(listHolder_2);
                                for (size_t i_2 = 0; i_2 < element_0.d.count; ++i_2) {
                                    if (![element_0.d[i_2] isKindOfClass:[MTRTestClusterClusterSimpleStruct class]]) {
                                        // Wrong kind of value.
                                        return CHIP_ERROR_INVALID_ARGUMENT;
                                    }
                                    auto element_2 = (MTRTestClusterClusterSimpleStruct *) element_0.d[i_2];
                                    listHolder_2->mList[i_2].a = element_2.a.unsignedCharValue;
                                    listHolder_2->mList[i_2].b = element_2.b.boolValue;
                                    listHolder_2->mList[i_2].c
                                        = static_cast<std::remove_reference_t<decltype(listHolder_2->mList[i_2].c)>>(
                                            element_2.c.unsignedCharValue);
                                    listHolder_2->mList[i_2].d = [self asByteSpan:element_2.d];
                                    listHolder_2->mList[i_2].e = [self asCharSpan:element_2.e];
                                    listHolder_2->mList[i_2].f
                                        = static_cast<std::remove_reference_t<decltype(listHolder_2->mList[i_2].f)>>(
                                            element_2.f.unsignedCharValue);
                                    listHolder_2->mList[i_2].g = element_2.g.floatValue;
                                    listHolder_2->mList[i_2].h = element_2.h.doubleValue;
                                }
                                listHolder_0->mList[i_0].d = ListType_2(listHolder_2->mList, element_0.d.count);
                            } else {
                                listHolder_0->mList[i_0].d = ListType_2();
                            }
                        }
                        {
                            using ListType_2 = std::remove_reference_t<decltype(listHolder_0->mList[i_0].e)>;
                            using ListMemberType_2 = ListMemberTypeGetter<ListType_2>::Type;
                            if (element_0.e.count != 0) {
                                auto * listHolder_2 = new ListHolder<ListMemberType_2>(element_0.e.count);
                                if (listHolder_2 == nullptr || listHolder_2->mList == nullptr) {
                                    return CHIP_ERROR_INVALID_ARGUMENT;
                                }
                                listFreer.add(listHolder_2);
                                for (size_t i_2 = 0; i_2 < element_0.e.count; ++i_2) {
                                    if (![element_0.e[i_2] isKindOfClass:[NSNumber class]]) {
                                        // Wrong kind of value.
                                        return CHIP_ERROR_INVALID_ARGUMENT;
                                    }
                                    auto element_2 = (NSNumber *) element_0.e[i_2];
                                    listHolder_2->mList[i_2] = element_2.unsignedIntValue;
                                }
                                listHolder_0->mList[i_0].e = ListType_2(listHolder_2->mList, element_0.e.count);
                            } else {
                                listHolder_0->mList[i_0].e = ListType_2();
                            }
                        }
                        {
                            using ListType_2 = std::remove_reference_t<decltype(listHolder_0->mList[i_0].f)>;
                            using ListMemberType_2 = ListMemberTypeGetter<ListType_2>::Type;
                            if (element_0.f.count != 0) {
                                auto * listHolder_2 = new ListHolder<ListMemberType_2>(element_0.f.count);
                                if (listHolder_2 == nullptr || listHolder_2->mList == nullptr) {
                                    return CHIP_ERROR_INVALID_ARGUMENT;
                                }
                                listFreer.add(listHolder_2);
                                for (size_t i_2 = 0; i_2 < element_0.f.count; ++i_2) {
                                    if (![element_0.f[i_2] isKindOfClass:[NSData class]]) {
                                        // Wrong kind of value.
                                        return CHIP_ERROR_INVALID_ARGUMENT;
                                    }
                                    auto element_2 = (NSData *) element_0.f[i_2];
                                    listHolder_2->mList[i_2] = [self asByteSpan:element_2];
                                }
                                listHolder_0->mList[i_0].f = ListType_2(listHolder_2->mList, element_0.f.count);
                            } else {
                                listHolder_0->mList[i_0].f = ListType_2();
                            }
                        }
                        {
                            using ListType_2 = std::remove_reference_t<decltype(listHolder_0->mList[i_0].g)>;
                            using ListMemberType_2 = ListMemberTypeGetter<ListType_2>::Type;
                            if (element_0.g.count != 0) {
                                auto * listHolder_2 = new ListHolder<ListMemberType_2>(element_0.g.count);
                                if (listHolder_2 == nullptr || listHolder_2->mList == nullptr) {
                                    return CHIP_ERROR_INVALID_ARGUMENT;
                                }
                                listFreer.add(listHolder_2);
                                for (size_t i_2 = 0; i_2 < element_0.g.count; ++i_2) {
                                    if (![element_0.g[i_2] isKindOfClass:[NSNumber class]]) {
                                        // Wrong kind of value.
                                        return CHIP_ERROR_INVALID_ARGUMENT;
                                    }
                                    auto element_2 = (NSNumber *) element_0.g[i_2];
                                    listHolder_2->mList[i_2] = element_2.unsignedCharValue;
                                }
                                listHolder_0->mList[i_0].g = ListType_2(listHolder_2->mList, element_0.g.count);
                            } else {
                                listHolder_0->mList[i_0].g = ListType_2();
                            }
                        }
                    }
                    request.arg1 = ListType_0(listHolder_0->mList, params.arg1.count);
                } else {
                    request.arg1 = ListType_0();
                }
            }
            {
                using ListType_0 = std::remove_reference_t<decltype(request.arg2)>;
                using ListMemberType_0 = ListMemberTypeGetter<ListType_0>::Type;
                if (params.arg2.count != 0) {
                    auto * listHolder_0 = new ListHolder<ListMemberType_0>(params.arg2.count);
                    if (listHolder_0 == nullptr || listHolder_0->mList == nullptr) {
                        return CHIP_ERROR_INVALID_ARGUMENT;
                    }
                    listFreer.add(listHolder_0);
                    for (size_t i_0 = 0; i_0 < params.arg2.count; ++i_0) {
                        if (![params.arg2[i_0] isKindOfClass:[MTRTestClusterClusterSimpleStruct class]]) {
                            // Wrong kind of value.
                            return CHIP_ERROR_INVALID_ARGUMENT;
                        }
                        auto element_0 = (MTRTestClusterClusterSimpleStruct *) params.arg2[i_0];
                        listHolder_0->mList[i_0].a = element_0.a.unsignedCharValue;
                        listHolder_0->mList[i_0].b = element_0.b.boolValue;
                        listHolder_0->mList[i_0].c = static_cast<std::remove_reference_t<decltype(listHolder_0->mList[i_0].c)>>(
                            element_0.c.unsignedCharValue);
                        listHolder_0->mList[i_0].d = [self asByteSpan:element_0.d];
                        listHolder_0->mList[i_0].e = [self asCharSpan:element_0.e];
                        listHolder_0->mList[i_0].f = static_cast<std::remove_reference_t<decltype(listHolder_0->mList[i_0].f)>>(
                            element_0.f.unsignedCharValue);
                        listHolder_0->mList[i_0].g = element_0.g.floatValue;
                        listHolder_0->mList[i_0].h = element_0.h.doubleValue;
                    }
                    request.arg2 = ListType_0(listHolder_0->mList, params.arg2.count);
                } else {
                    request.arg2 = ListType_0();
                }
            }
            {
                using ListType_0 = std::remove_reference_t<decltype(request.arg3)>;
                using ListMemberType_0 = ListMemberTypeGetter<ListType_0>::Type;
                if (params.arg3.count != 0) {
                    auto * listHolder_0 = new ListHolder<ListMemberType_0>(params.arg3.count);
                    if (listHolder_0 == nullptr || listHolder_0->mList == nullptr) {
                        return CHIP_ERROR_INVALID_ARGUMENT;
                    }
                    listFreer.add(listHolder_0);
                    for (size_t i_0 = 0; i_0 < params.arg3.count; ++i_0) {
                        if (![params.arg3[i_0] isKindOfClass:[NSNumber class]]) {
                            // Wrong kind of value.
                            return CHIP_ERROR_INVALID_ARGUMENT;
                        }
                        auto element_0 = (NSNumber *) params.arg3[i_0];
                        listHolder_0->mList[i_0]
                            = static_cast<std::remove_reference_t<decltype(listHolder_0->mList[i_0])>>(element_0.unsignedCharValue);
                    }
                    request.arg3 = ListType_0(listHolder_0->mList, params.arg3.count);
                } else {
                    request.arg3 = ListType_0();
                }
            }
            {
                using ListType_0 = std::remove_reference_t<decltype(request.arg4)>;
                using ListMemberType_0 = ListMemberTypeGetter<ListType_0>::Type;
                if (params.arg4.count != 0) {
                    auto * listHolder_0 = new ListHolder<ListMemberType_0>(params.arg4.count);
                    if (listHolder_0 == nullptr || listHolder_0->mList == nullptr) {
                        return CHIP_ERROR_INVALID_ARGUMENT;
                    }
                    listFreer.add(listHolder_0);
                    for (size_t i_0 = 0; i_0 < params.arg4.count; ++i_0) {
                        if (![params.arg4[i_0] isKindOfClass:[NSNumber class]]) {
                            // Wrong kind of value.
                            return CHIP_ERROR_INVALID_ARGUMENT;
                        }
                        auto element_0 = (NSNumber *) params.arg4[i_0];
                        listHolder_0->mList[i_0] = element_0.boolValue;
                    }
                    request.arg4 = ListType_0(listHolder_0->mList, params.arg4.count);
                } else {
                    request.arg4 = ListType_0();
                }
            }
            request.arg5 = static_cast<std::remove_reference_t<decltype(request.arg5)>>(params.arg5.unsignedCharValue);
            request.arg6 = params.arg6.boolValue;

            auto successFn = Callback<TestClusterClusterTestStructArrayArgumentResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)testStructArgumentRequestWithParams:(MTRTestClusterClusterTestStructArgumentRequestParams *)params
                          completionHandler:(void (^)(MTRTestClusterClusterBooleanResponseParams * _Nullable data,
                                                NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRTestClusterClusterBooleanResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            TestCluster::Commands::TestStructArgumentRequest::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.arg1.a = params.arg1.a.unsignedCharValue;
            request.arg1.b = params.arg1.b.boolValue;
            request.arg1.c = static_cast<std::remove_reference_t<decltype(request.arg1.c)>>(params.arg1.c.unsignedCharValue);
            request.arg1.d = [self asByteSpan:params.arg1.d];
            request.arg1.e = [self asCharSpan:params.arg1.e];
            request.arg1.f = static_cast<std::remove_reference_t<decltype(request.arg1.f)>>(params.arg1.f.unsignedCharValue);
            request.arg1.g = params.arg1.g.floatValue;
            request.arg1.h = params.arg1.h.doubleValue;

            auto successFn = Callback<TestClusterClusterBooleanResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)testNestedStructArgumentRequestWithParams:(MTRTestClusterClusterTestNestedStructArgumentRequestParams *)params
                                completionHandler:(void (^)(MTRTestClusterClusterBooleanResponseParams * _Nullable data,
                                                      NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRTestClusterClusterBooleanResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            TestCluster::Commands::TestNestedStructArgumentRequest::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.arg1.a = params.arg1.a.unsignedCharValue;
            request.arg1.b = params.arg1.b.boolValue;
            request.arg1.c.a = params.arg1.c.a.unsignedCharValue;
            request.arg1.c.b = params.arg1.c.b.boolValue;
            request.arg1.c.c = static_cast<std::remove_reference_t<decltype(request.arg1.c.c)>>(params.arg1.c.c.unsignedCharValue);
            request.arg1.c.d = [self asByteSpan:params.arg1.c.d];
            request.arg1.c.e = [self asCharSpan:params.arg1.c.e];
            request.arg1.c.f = static_cast<std::remove_reference_t<decltype(request.arg1.c.f)>>(params.arg1.c.f.unsignedCharValue);
            request.arg1.c.g = params.arg1.c.g.floatValue;
            request.arg1.c.h = params.arg1.c.h.doubleValue;

            auto successFn = Callback<TestClusterClusterBooleanResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)testListStructArgumentRequestWithParams:(MTRTestClusterClusterTestListStructArgumentRequestParams *)params
                              completionHandler:(void (^)(MTRTestClusterClusterBooleanResponseParams * _Nullable data,
                                                    NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRTestClusterClusterBooleanResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            TestCluster::Commands::TestListStructArgumentRequest::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            {
                using ListType_0 = std::remove_reference_t<decltype(request.arg1)>;
                using ListMemberType_0 = ListMemberTypeGetter<ListType_0>::Type;
                if (params.arg1.count != 0) {
                    auto * listHolder_0 = new ListHolder<ListMemberType_0>(params.arg1.count);
                    if (listHolder_0 == nullptr || listHolder_0->mList == nullptr) {
                        return CHIP_ERROR_INVALID_ARGUMENT;
                    }
                    listFreer.add(listHolder_0);
                    for (size_t i_0 = 0; i_0 < params.arg1.count; ++i_0) {
                        if (![params.arg1[i_0] isKindOfClass:[MTRTestClusterClusterSimpleStruct class]]) {
                            // Wrong kind of value.
                            return CHIP_ERROR_INVALID_ARGUMENT;
                        }
                        auto element_0 = (MTRTestClusterClusterSimpleStruct *) params.arg1[i_0];
                        listHolder_0->mList[i_0].a = element_0.a.unsignedCharValue;
                        listHolder_0->mList[i_0].b = element_0.b.boolValue;
                        listHolder_0->mList[i_0].c = static_cast<std::remove_reference_t<decltype(listHolder_0->mList[i_0].c)>>(
                            element_0.c.unsignedCharValue);
                        listHolder_0->mList[i_0].d = [self asByteSpan:element_0.d];
                        listHolder_0->mList[i_0].e = [self asCharSpan:element_0.e];
                        listHolder_0->mList[i_0].f = static_cast<std::remove_reference_t<decltype(listHolder_0->mList[i_0].f)>>(
                            element_0.f.unsignedCharValue);
                        listHolder_0->mList[i_0].g = element_0.g.floatValue;
                        listHolder_0->mList[i_0].h = element_0.h.doubleValue;
                    }
                    request.arg1 = ListType_0(listHolder_0->mList, params.arg1.count);
                } else {
                    request.arg1 = ListType_0();
                }
            }

            auto successFn = Callback<TestClusterClusterBooleanResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)testListInt8UArgumentRequestWithParams:(MTRTestClusterClusterTestListInt8UArgumentRequestParams *)params
                             completionHandler:(void (^)(MTRTestClusterClusterBooleanResponseParams * _Nullable data,
                                                   NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRTestClusterClusterBooleanResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            TestCluster::Commands::TestListInt8UArgumentRequest::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            {
                using ListType_0 = std::remove_reference_t<decltype(request.arg1)>;
                using ListMemberType_0 = ListMemberTypeGetter<ListType_0>::Type;
                if (params.arg1.count != 0) {
                    auto * listHolder_0 = new ListHolder<ListMemberType_0>(params.arg1.count);
                    if (listHolder_0 == nullptr || listHolder_0->mList == nullptr) {
                        return CHIP_ERROR_INVALID_ARGUMENT;
                    }
                    listFreer.add(listHolder_0);
                    for (size_t i_0 = 0; i_0 < params.arg1.count; ++i_0) {
                        if (![params.arg1[i_0] isKindOfClass:[NSNumber class]]) {
                            // Wrong kind of value.
                            return CHIP_ERROR_INVALID_ARGUMENT;
                        }
                        auto element_0 = (NSNumber *) params.arg1[i_0];
                        listHolder_0->mList[i_0] = element_0.unsignedCharValue;
                    }
                    request.arg1 = ListType_0(listHolder_0->mList, params.arg1.count);
                } else {
                    request.arg1 = ListType_0();
                }
            }

            auto successFn = Callback<TestClusterClusterBooleanResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)testNestedStructListArgumentRequestWithParams:(MTRTestClusterClusterTestNestedStructListArgumentRequestParams *)params
                                    completionHandler:(void (^)(MTRTestClusterClusterBooleanResponseParams * _Nullable data,
                                                          NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRTestClusterClusterBooleanResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            TestCluster::Commands::TestNestedStructListArgumentRequest::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.arg1.a = params.arg1.a.unsignedCharValue;
            request.arg1.b = params.arg1.b.boolValue;
            request.arg1.c.a = params.arg1.c.a.unsignedCharValue;
            request.arg1.c.b = params.arg1.c.b.boolValue;
            request.arg1.c.c = static_cast<std::remove_reference_t<decltype(request.arg1.c.c)>>(params.arg1.c.c.unsignedCharValue);
            request.arg1.c.d = [self asByteSpan:params.arg1.c.d];
            request.arg1.c.e = [self asCharSpan:params.arg1.c.e];
            request.arg1.c.f = static_cast<std::remove_reference_t<decltype(request.arg1.c.f)>>(params.arg1.c.f.unsignedCharValue);
            request.arg1.c.g = params.arg1.c.g.floatValue;
            request.arg1.c.h = params.arg1.c.h.doubleValue;
            {
                using ListType_1 = std::remove_reference_t<decltype(request.arg1.d)>;
                using ListMemberType_1 = ListMemberTypeGetter<ListType_1>::Type;
                if (params.arg1.d.count != 0) {
                    auto * listHolder_1 = new ListHolder<ListMemberType_1>(params.arg1.d.count);
                    if (listHolder_1 == nullptr || listHolder_1->mList == nullptr) {
                        return CHIP_ERROR_INVALID_ARGUMENT;
                    }
                    listFreer.add(listHolder_1);
                    for (size_t i_1 = 0; i_1 < params.arg1.d.count; ++i_1) {
                        if (![params.arg1.d[i_1] isKindOfClass:[MTRTestClusterClusterSimpleStruct class]]) {
                            // Wrong kind of value.
                            return CHIP_ERROR_INVALID_ARGUMENT;
                        }
                        auto element_1 = (MTRTestClusterClusterSimpleStruct *) params.arg1.d[i_1];
                        listHolder_1->mList[i_1].a = element_1.a.unsignedCharValue;
                        listHolder_1->mList[i_1].b = element_1.b.boolValue;
                        listHolder_1->mList[i_1].c = static_cast<std::remove_reference_t<decltype(listHolder_1->mList[i_1].c)>>(
                            element_1.c.unsignedCharValue);
                        listHolder_1->mList[i_1].d = [self asByteSpan:element_1.d];
                        listHolder_1->mList[i_1].e = [self asCharSpan:element_1.e];
                        listHolder_1->mList[i_1].f = static_cast<std::remove_reference_t<decltype(listHolder_1->mList[i_1].f)>>(
                            element_1.f.unsignedCharValue);
                        listHolder_1->mList[i_1].g = element_1.g.floatValue;
                        listHolder_1->mList[i_1].h = element_1.h.doubleValue;
                    }
                    request.arg1.d = ListType_1(listHolder_1->mList, params.arg1.d.count);
                } else {
                    request.arg1.d = ListType_1();
                }
            }
            {
                using ListType_1 = std::remove_reference_t<decltype(request.arg1.e)>;
                using ListMemberType_1 = ListMemberTypeGetter<ListType_1>::Type;
                if (params.arg1.e.count != 0) {
                    auto * listHolder_1 = new ListHolder<ListMemberType_1>(params.arg1.e.count);
                    if (listHolder_1 == nullptr || listHolder_1->mList == nullptr) {
                        return CHIP_ERROR_INVALID_ARGUMENT;
                    }
                    listFreer.add(listHolder_1);
                    for (size_t i_1 = 0; i_1 < params.arg1.e.count; ++i_1) {
                        if (![params.arg1.e[i_1] isKindOfClass:[NSNumber class]]) {
                            // Wrong kind of value.
                            return CHIP_ERROR_INVALID_ARGUMENT;
                        }
                        auto element_1 = (NSNumber *) params.arg1.e[i_1];
                        listHolder_1->mList[i_1] = element_1.unsignedIntValue;
                    }
                    request.arg1.e = ListType_1(listHolder_1->mList, params.arg1.e.count);
                } else {
                    request.arg1.e = ListType_1();
                }
            }
            {
                using ListType_1 = std::remove_reference_t<decltype(request.arg1.f)>;
                using ListMemberType_1 = ListMemberTypeGetter<ListType_1>::Type;
                if (params.arg1.f.count != 0) {
                    auto * listHolder_1 = new ListHolder<ListMemberType_1>(params.arg1.f.count);
                    if (listHolder_1 == nullptr || listHolder_1->mList == nullptr) {
                        return CHIP_ERROR_INVALID_ARGUMENT;
                    }
                    listFreer.add(listHolder_1);
                    for (size_t i_1 = 0; i_1 < params.arg1.f.count; ++i_1) {
                        if (![params.arg1.f[i_1] isKindOfClass:[NSData class]]) {
                            // Wrong kind of value.
                            return CHIP_ERROR_INVALID_ARGUMENT;
                        }
                        auto element_1 = (NSData *) params.arg1.f[i_1];
                        listHolder_1->mList[i_1] = [self asByteSpan:element_1];
                    }
                    request.arg1.f = ListType_1(listHolder_1->mList, params.arg1.f.count);
                } else {
                    request.arg1.f = ListType_1();
                }
            }
            {
                using ListType_1 = std::remove_reference_t<decltype(request.arg1.g)>;
                using ListMemberType_1 = ListMemberTypeGetter<ListType_1>::Type;
                if (params.arg1.g.count != 0) {
                    auto * listHolder_1 = new ListHolder<ListMemberType_1>(params.arg1.g.count);
                    if (listHolder_1 == nullptr || listHolder_1->mList == nullptr) {
                        return CHIP_ERROR_INVALID_ARGUMENT;
                    }
                    listFreer.add(listHolder_1);
                    for (size_t i_1 = 0; i_1 < params.arg1.g.count; ++i_1) {
                        if (![params.arg1.g[i_1] isKindOfClass:[NSNumber class]]) {
                            // Wrong kind of value.
                            return CHIP_ERROR_INVALID_ARGUMENT;
                        }
                        auto element_1 = (NSNumber *) params.arg1.g[i_1];
                        listHolder_1->mList[i_1] = element_1.unsignedCharValue;
                    }
                    request.arg1.g = ListType_1(listHolder_1->mList, params.arg1.g.count);
                } else {
                    request.arg1.g = ListType_1();
                }
            }

            auto successFn = Callback<TestClusterClusterBooleanResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)testListNestedStructListArgumentRequestWithParams:
            (MTRTestClusterClusterTestListNestedStructListArgumentRequestParams *)params
                                        completionHandler:(void (^)(MTRTestClusterClusterBooleanResponseParams * _Nullable data,
                                                              NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRTestClusterClusterBooleanResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            TestCluster::Commands::TestListNestedStructListArgumentRequest::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            {
                using ListType_0 = std::remove_reference_t<decltype(request.arg1)>;
                using ListMemberType_0 = ListMemberTypeGetter<ListType_0>::Type;
                if (params.arg1.count != 0) {
                    auto * listHolder_0 = new ListHolder<ListMemberType_0>(params.arg1.count);
                    if (listHolder_0 == nullptr || listHolder_0->mList == nullptr) {
                        return CHIP_ERROR_INVALID_ARGUMENT;
                    }
                    listFreer.add(listHolder_0);
                    for (size_t i_0 = 0; i_0 < params.arg1.count; ++i_0) {
                        if (![params.arg1[i_0] isKindOfClass:[MTRTestClusterClusterNestedStructList class]]) {
                            // Wrong kind of value.
                            return CHIP_ERROR_INVALID_ARGUMENT;
                        }
                        auto element_0 = (MTRTestClusterClusterNestedStructList *) params.arg1[i_0];
                        listHolder_0->mList[i_0].a = element_0.a.unsignedCharValue;
                        listHolder_0->mList[i_0].b = element_0.b.boolValue;
                        listHolder_0->mList[i_0].c.a = element_0.c.a.unsignedCharValue;
                        listHolder_0->mList[i_0].c.b = element_0.c.b.boolValue;
                        listHolder_0->mList[i_0].c.c = static_cast<std::remove_reference_t<decltype(listHolder_0->mList[i_0].c.c)>>(
                            element_0.c.c.unsignedCharValue);
                        listHolder_0->mList[i_0].c.d = [self asByteSpan:element_0.c.d];
                        listHolder_0->mList[i_0].c.e = [self asCharSpan:element_0.c.e];
                        listHolder_0->mList[i_0].c.f = static_cast<std::remove_reference_t<decltype(listHolder_0->mList[i_0].c.f)>>(
                            element_0.c.f.unsignedCharValue);
                        listHolder_0->mList[i_0].c.g = element_0.c.g.floatValue;
                        listHolder_0->mList[i_0].c.h = element_0.c.h.doubleValue;
                        {
                            using ListType_2 = std::remove_reference_t<decltype(listHolder_0->mList[i_0].d)>;
                            using ListMemberType_2 = ListMemberTypeGetter<ListType_2>::Type;
                            if (element_0.d.count != 0) {
                                auto * listHolder_2 = new ListHolder<ListMemberType_2>(element_0.d.count);
                                if (listHolder_2 == nullptr || listHolder_2->mList == nullptr) {
                                    return CHIP_ERROR_INVALID_ARGUMENT;
                                }
                                listFreer.add(listHolder_2);
                                for (size_t i_2 = 0; i_2 < element_0.d.count; ++i_2) {
                                    if (![element_0.d[i_2] isKindOfClass:[MTRTestClusterClusterSimpleStruct class]]) {
                                        // Wrong kind of value.
                                        return CHIP_ERROR_INVALID_ARGUMENT;
                                    }
                                    auto element_2 = (MTRTestClusterClusterSimpleStruct *) element_0.d[i_2];
                                    listHolder_2->mList[i_2].a = element_2.a.unsignedCharValue;
                                    listHolder_2->mList[i_2].b = element_2.b.boolValue;
                                    listHolder_2->mList[i_2].c
                                        = static_cast<std::remove_reference_t<decltype(listHolder_2->mList[i_2].c)>>(
                                            element_2.c.unsignedCharValue);
                                    listHolder_2->mList[i_2].d = [self asByteSpan:element_2.d];
                                    listHolder_2->mList[i_2].e = [self asCharSpan:element_2.e];
                                    listHolder_2->mList[i_2].f
                                        = static_cast<std::remove_reference_t<decltype(listHolder_2->mList[i_2].f)>>(
                                            element_2.f.unsignedCharValue);
                                    listHolder_2->mList[i_2].g = element_2.g.floatValue;
                                    listHolder_2->mList[i_2].h = element_2.h.doubleValue;
                                }
                                listHolder_0->mList[i_0].d = ListType_2(listHolder_2->mList, element_0.d.count);
                            } else {
                                listHolder_0->mList[i_0].d = ListType_2();
                            }
                        }
                        {
                            using ListType_2 = std::remove_reference_t<decltype(listHolder_0->mList[i_0].e)>;
                            using ListMemberType_2 = ListMemberTypeGetter<ListType_2>::Type;
                            if (element_0.e.count != 0) {
                                auto * listHolder_2 = new ListHolder<ListMemberType_2>(element_0.e.count);
                                if (listHolder_2 == nullptr || listHolder_2->mList == nullptr) {
                                    return CHIP_ERROR_INVALID_ARGUMENT;
                                }
                                listFreer.add(listHolder_2);
                                for (size_t i_2 = 0; i_2 < element_0.e.count; ++i_2) {
                                    if (![element_0.e[i_2] isKindOfClass:[NSNumber class]]) {
                                        // Wrong kind of value.
                                        return CHIP_ERROR_INVALID_ARGUMENT;
                                    }
                                    auto element_2 = (NSNumber *) element_0.e[i_2];
                                    listHolder_2->mList[i_2] = element_2.unsignedIntValue;
                                }
                                listHolder_0->mList[i_0].e = ListType_2(listHolder_2->mList, element_0.e.count);
                            } else {
                                listHolder_0->mList[i_0].e = ListType_2();
                            }
                        }
                        {
                            using ListType_2 = std::remove_reference_t<decltype(listHolder_0->mList[i_0].f)>;
                            using ListMemberType_2 = ListMemberTypeGetter<ListType_2>::Type;
                            if (element_0.f.count != 0) {
                                auto * listHolder_2 = new ListHolder<ListMemberType_2>(element_0.f.count);
                                if (listHolder_2 == nullptr || listHolder_2->mList == nullptr) {
                                    return CHIP_ERROR_INVALID_ARGUMENT;
                                }
                                listFreer.add(listHolder_2);
                                for (size_t i_2 = 0; i_2 < element_0.f.count; ++i_2) {
                                    if (![element_0.f[i_2] isKindOfClass:[NSData class]]) {
                                        // Wrong kind of value.
                                        return CHIP_ERROR_INVALID_ARGUMENT;
                                    }
                                    auto element_2 = (NSData *) element_0.f[i_2];
                                    listHolder_2->mList[i_2] = [self asByteSpan:element_2];
                                }
                                listHolder_0->mList[i_0].f = ListType_2(listHolder_2->mList, element_0.f.count);
                            } else {
                                listHolder_0->mList[i_0].f = ListType_2();
                            }
                        }
                        {
                            using ListType_2 = std::remove_reference_t<decltype(listHolder_0->mList[i_0].g)>;
                            using ListMemberType_2 = ListMemberTypeGetter<ListType_2>::Type;
                            if (element_0.g.count != 0) {
                                auto * listHolder_2 = new ListHolder<ListMemberType_2>(element_0.g.count);
                                if (listHolder_2 == nullptr || listHolder_2->mList == nullptr) {
                                    return CHIP_ERROR_INVALID_ARGUMENT;
                                }
                                listFreer.add(listHolder_2);
                                for (size_t i_2 = 0; i_2 < element_0.g.count; ++i_2) {
                                    if (![element_0.g[i_2] isKindOfClass:[NSNumber class]]) {
                                        // Wrong kind of value.
                                        return CHIP_ERROR_INVALID_ARGUMENT;
                                    }
                                    auto element_2 = (NSNumber *) element_0.g[i_2];
                                    listHolder_2->mList[i_2] = element_2.unsignedCharValue;
                                }
                                listHolder_0->mList[i_0].g = ListType_2(listHolder_2->mList, element_0.g.count);
                            } else {
                                listHolder_0->mList[i_0].g = ListType_2();
                            }
                        }
                    }
                    request.arg1 = ListType_0(listHolder_0->mList, params.arg1.count);
                } else {
                    request.arg1 = ListType_0();
                }
            }

            auto successFn = Callback<TestClusterClusterBooleanResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)testListInt8UReverseRequestWithParams:(MTRTestClusterClusterTestListInt8UReverseRequestParams *)params
                            completionHandler:(void (^)(MTRTestClusterClusterTestListInt8UReverseResponseParams * _Nullable data,
                                                  NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRTestClusterClusterTestListInt8UReverseResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            TestCluster::Commands::TestListInt8UReverseRequest::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            {
                using ListType_0 = std::remove_reference_t<decltype(request.arg1)>;
                using ListMemberType_0 = ListMemberTypeGetter<ListType_0>::Type;
                if (params.arg1.count != 0) {
                    auto * listHolder_0 = new ListHolder<ListMemberType_0>(params.arg1.count);
                    if (listHolder_0 == nullptr || listHolder_0->mList == nullptr) {
                        return CHIP_ERROR_INVALID_ARGUMENT;
                    }
                    listFreer.add(listHolder_0);
                    for (size_t i_0 = 0; i_0 < params.arg1.count; ++i_0) {
                        if (![params.arg1[i_0] isKindOfClass:[NSNumber class]]) {
                            // Wrong kind of value.
                            return CHIP_ERROR_INVALID_ARGUMENT;
                        }
                        auto element_0 = (NSNumber *) params.arg1[i_0];
                        listHolder_0->mList[i_0] = element_0.unsignedCharValue;
                    }
                    request.arg1 = ListType_0(listHolder_0->mList, params.arg1.count);
                } else {
                    request.arg1 = ListType_0();
                }
            }

            auto successFn = Callback<TestClusterClusterTestListInt8UReverseResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)testEnumsRequestWithParams:(MTRTestClusterClusterTestEnumsRequestParams *)params
                 completionHandler:(void (^)(MTRTestClusterClusterTestEnumsResponseParams * _Nullable data,
                                       NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRTestClusterClusterTestEnumsResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            TestCluster::Commands::TestEnumsRequest::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.arg1 = static_cast<std::remove_reference_t<decltype(request.arg1)>>(params.arg1.unsignedShortValue);
            request.arg2 = static_cast<std::remove_reference_t<decltype(request.arg2)>>(params.arg2.unsignedCharValue);

            auto successFn = Callback<TestClusterClusterTestEnumsResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)testNullableOptionalRequestWithParams:(MTRTestClusterClusterTestNullableOptionalRequestParams * _Nullable)params
                            completionHandler:(void (^)(MTRTestClusterClusterTestNullableOptionalResponseParams * _Nullable data,
                                                  NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRTestClusterClusterTestNullableOptionalResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            TestCluster::Commands::TestNullableOptionalRequest::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            if (params != nil) {
                if (params.arg1 != nil) {
                    auto & definedValue_0 = request.arg1.Emplace();
                    if (params.arg1 == nil) {
                        definedValue_0.SetNull();
                    } else {
                        auto & nonNullValue_1 = definedValue_0.SetNonNull();
                        nonNullValue_1 = params.arg1.unsignedCharValue;
                    }
                }
            }

            auto successFn = Callback<TestClusterClusterTestNullableOptionalResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)testComplexNullableOptionalRequestWithParams:(MTRTestClusterClusterTestComplexNullableOptionalRequestParams *)params
                                   completionHandler:
                                       (void (^)(MTRTestClusterClusterTestComplexNullableOptionalResponseParams * _Nullable data,
                                           NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRTestClusterClusterTestComplexNullableOptionalResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            TestCluster::Commands::TestComplexNullableOptionalRequest::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            if (params.nullableInt == nil) {
                request.nullableInt.SetNull();
            } else {
                auto & nonNullValue_0 = request.nullableInt.SetNonNull();
                nonNullValue_0 = params.nullableInt.unsignedShortValue;
            }
            if (params.optionalInt != nil) {
                auto & definedValue_0 = request.optionalInt.Emplace();
                definedValue_0 = params.optionalInt.unsignedShortValue;
            }
            if (params.nullableOptionalInt != nil) {
                auto & definedValue_0 = request.nullableOptionalInt.Emplace();
                if (params.nullableOptionalInt == nil) {
                    definedValue_0.SetNull();
                } else {
                    auto & nonNullValue_1 = definedValue_0.SetNonNull();
                    nonNullValue_1 = params.nullableOptionalInt.unsignedShortValue;
                }
            }
            if (params.nullableString == nil) {
                request.nullableString.SetNull();
            } else {
                auto & nonNullValue_0 = request.nullableString.SetNonNull();
                nonNullValue_0 = [self asCharSpan:params.nullableString];
            }
            if (params.optionalString != nil) {
                auto & definedValue_0 = request.optionalString.Emplace();
                definedValue_0 = [self asCharSpan:params.optionalString];
            }
            if (params.nullableOptionalString != nil) {
                auto & definedValue_0 = request.nullableOptionalString.Emplace();
                if (params.nullableOptionalString == nil) {
                    definedValue_0.SetNull();
                } else {
                    auto & nonNullValue_1 = definedValue_0.SetNonNull();
                    nonNullValue_1 = [self asCharSpan:params.nullableOptionalString];
                }
            }
            if (params.nullableStruct == nil) {
                request.nullableStruct.SetNull();
            } else {
                auto & nonNullValue_0 = request.nullableStruct.SetNonNull();
                nonNullValue_0.a = params.nullableStruct.a.unsignedCharValue;
                nonNullValue_0.b = params.nullableStruct.b.boolValue;
                nonNullValue_0.c
                    = static_cast<std::remove_reference_t<decltype(nonNullValue_0.c)>>(params.nullableStruct.c.unsignedCharValue);
                nonNullValue_0.d = [self asByteSpan:params.nullableStruct.d];
                nonNullValue_0.e = [self asCharSpan:params.nullableStruct.e];
                nonNullValue_0.f
                    = static_cast<std::remove_reference_t<decltype(nonNullValue_0.f)>>(params.nullableStruct.f.unsignedCharValue);
                nonNullValue_0.g = params.nullableStruct.g.floatValue;
                nonNullValue_0.h = params.nullableStruct.h.doubleValue;
            }
            if (params.optionalStruct != nil) {
                auto & definedValue_0 = request.optionalStruct.Emplace();
                definedValue_0.a = params.optionalStruct.a.unsignedCharValue;
                definedValue_0.b = params.optionalStruct.b.boolValue;
                definedValue_0.c
                    = static_cast<std::remove_reference_t<decltype(definedValue_0.c)>>(params.optionalStruct.c.unsignedCharValue);
                definedValue_0.d = [self asByteSpan:params.optionalStruct.d];
                definedValue_0.e = [self asCharSpan:params.optionalStruct.e];
                definedValue_0.f
                    = static_cast<std::remove_reference_t<decltype(definedValue_0.f)>>(params.optionalStruct.f.unsignedCharValue);
                definedValue_0.g = params.optionalStruct.g.floatValue;
                definedValue_0.h = params.optionalStruct.h.doubleValue;
            }
            if (params.nullableOptionalStruct != nil) {
                auto & definedValue_0 = request.nullableOptionalStruct.Emplace();
                if (params.nullableOptionalStruct == nil) {
                    definedValue_0.SetNull();
                } else {
                    auto & nonNullValue_1 = definedValue_0.SetNonNull();
                    nonNullValue_1.a = params.nullableOptionalStruct.a.unsignedCharValue;
                    nonNullValue_1.b = params.nullableOptionalStruct.b.boolValue;
                    nonNullValue_1.c = static_cast<std::remove_reference_t<decltype(nonNullValue_1.c)>>(
                        params.nullableOptionalStruct.c.unsignedCharValue);
                    nonNullValue_1.d = [self asByteSpan:params.nullableOptionalStruct.d];
                    nonNullValue_1.e = [self asCharSpan:params.nullableOptionalStruct.e];
                    nonNullValue_1.f = static_cast<std::remove_reference_t<decltype(nonNullValue_1.f)>>(
                        params.nullableOptionalStruct.f.unsignedCharValue);
                    nonNullValue_1.g = params.nullableOptionalStruct.g.floatValue;
                    nonNullValue_1.h = params.nullableOptionalStruct.h.doubleValue;
                }
            }
            if (params.nullableList == nil) {
                request.nullableList.SetNull();
            } else {
                auto & nonNullValue_0 = request.nullableList.SetNonNull();
                {
                    using ListType_1 = std::remove_reference_t<decltype(nonNullValue_0)>;
                    using ListMemberType_1 = ListMemberTypeGetter<ListType_1>::Type;
                    if (params.nullableList.count != 0) {
                        auto * listHolder_1 = new ListHolder<ListMemberType_1>(params.nullableList.count);
                        if (listHolder_1 == nullptr || listHolder_1->mList == nullptr) {
                            return CHIP_ERROR_INVALID_ARGUMENT;
                        }
                        listFreer.add(listHolder_1);
                        for (size_t i_1 = 0; i_1 < params.nullableList.count; ++i_1) {
                            if (![params.nullableList[i_1] isKindOfClass:[NSNumber class]]) {
                                // Wrong kind of value.
                                return CHIP_ERROR_INVALID_ARGUMENT;
                            }
                            auto element_1 = (NSNumber *) params.nullableList[i_1];
                            listHolder_1->mList[i_1] = static_cast<std::remove_reference_t<decltype(listHolder_1->mList[i_1])>>(
                                element_1.unsignedCharValue);
                        }
                        nonNullValue_0 = ListType_1(listHolder_1->mList, params.nullableList.count);
                    } else {
                        nonNullValue_0 = ListType_1();
                    }
                }
            }
            if (params.optionalList != nil) {
                auto & definedValue_0 = request.optionalList.Emplace();
                {
                    using ListType_1 = std::remove_reference_t<decltype(definedValue_0)>;
                    using ListMemberType_1 = ListMemberTypeGetter<ListType_1>::Type;
                    if (params.optionalList.count != 0) {
                        auto * listHolder_1 = new ListHolder<ListMemberType_1>(params.optionalList.count);
                        if (listHolder_1 == nullptr || listHolder_1->mList == nullptr) {
                            return CHIP_ERROR_INVALID_ARGUMENT;
                        }
                        listFreer.add(listHolder_1);
                        for (size_t i_1 = 0; i_1 < params.optionalList.count; ++i_1) {
                            if (![params.optionalList[i_1] isKindOfClass:[NSNumber class]]) {
                                // Wrong kind of value.
                                return CHIP_ERROR_INVALID_ARGUMENT;
                            }
                            auto element_1 = (NSNumber *) params.optionalList[i_1];
                            listHolder_1->mList[i_1] = static_cast<std::remove_reference_t<decltype(listHolder_1->mList[i_1])>>(
                                element_1.unsignedCharValue);
                        }
                        definedValue_0 = ListType_1(listHolder_1->mList, params.optionalList.count);
                    } else {
                        definedValue_0 = ListType_1();
                    }
                }
            }
            if (params.nullableOptionalList != nil) {
                auto & definedValue_0 = request.nullableOptionalList.Emplace();
                if (params.nullableOptionalList == nil) {
                    definedValue_0.SetNull();
                } else {
                    auto & nonNullValue_1 = definedValue_0.SetNonNull();
                    {
                        using ListType_2 = std::remove_reference_t<decltype(nonNullValue_1)>;
                        using ListMemberType_2 = ListMemberTypeGetter<ListType_2>::Type;
                        if (params.nullableOptionalList.count != 0) {
                            auto * listHolder_2 = new ListHolder<ListMemberType_2>(params.nullableOptionalList.count);
                            if (listHolder_2 == nullptr || listHolder_2->mList == nullptr) {
                                return CHIP_ERROR_INVALID_ARGUMENT;
                            }
                            listFreer.add(listHolder_2);
                            for (size_t i_2 = 0; i_2 < params.nullableOptionalList.count; ++i_2) {
                                if (![params.nullableOptionalList[i_2] isKindOfClass:[NSNumber class]]) {
                                    // Wrong kind of value.
                                    return CHIP_ERROR_INVALID_ARGUMENT;
                                }
                                auto element_2 = (NSNumber *) params.nullableOptionalList[i_2];
                                listHolder_2->mList[i_2] = static_cast<std::remove_reference_t<decltype(listHolder_2->mList[i_2])>>(
                                    element_2.unsignedCharValue);
                            }
                            nonNullValue_1 = ListType_2(listHolder_2->mList, params.nullableOptionalList.count);
                        } else {
                            nonNullValue_1 = ListType_2();
                        }
                    }
                }
            }

            auto successFn = Callback<TestClusterClusterTestComplexNullableOptionalResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)simpleStructEchoRequestWithParams:(MTRTestClusterClusterSimpleStructEchoRequestParams *)params
                        completionHandler:(void (^)(MTRTestClusterClusterSimpleStructResponseParams * _Nullable data,
                                              NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRTestClusterClusterSimpleStructResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            TestCluster::Commands::SimpleStructEchoRequest::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.arg1.a = params.arg1.a.unsignedCharValue;
            request.arg1.b = params.arg1.b.boolValue;
            request.arg1.c = static_cast<std::remove_reference_t<decltype(request.arg1.c)>>(params.arg1.c.unsignedCharValue);
            request.arg1.d = [self asByteSpan:params.arg1.d];
            request.arg1.e = [self asCharSpan:params.arg1.e];
            request.arg1.f = static_cast<std::remove_reference_t<decltype(request.arg1.f)>>(params.arg1.f.unsignedCharValue);
            request.arg1.g = params.arg1.g.floatValue;
            request.arg1.h = params.arg1.h.doubleValue;

            auto successFn = Callback<TestClusterClusterSimpleStructResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)timedInvokeRequestWithCompletionHandler:(StatusCompletion)completionHandler
{
    [self timedInvokeRequestWithParams:nil completionHandler:completionHandler];
}
- (void)timedInvokeRequestWithParams:(MTRTestClusterClusterTimedInvokeRequestParams * _Nullable)params
                   completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            TestCluster::Commands::TimedInvokeRequest::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            if (!timedInvokeTimeoutMs.HasValue()) {
                timedInvokeTimeoutMs.SetValue(10000);
            }

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)testSimpleOptionalArgumentRequestWithParams:(MTRTestClusterClusterTestSimpleOptionalArgumentRequestParams * _Nullable)params
                                  completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRCommandSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable value, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            TestCluster::Commands::TestSimpleOptionalArgumentRequest::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            if (params != nil) {
                if (params.arg1 != nil) {
                    auto & definedValue_0 = request.arg1.Emplace();
                    definedValue_0 = params.arg1.boolValue;
                }
            }

            auto successFn = Callback<CommandSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)testEmitTestEventRequestWithParams:(MTRTestClusterClusterTestEmitTestEventRequestParams *)params
                         completionHandler:(void (^)(MTRTestClusterClusterTestEmitTestEventResponseParams * _Nullable data,
                                               NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRTestClusterClusterTestEmitTestEventResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            TestCluster::Commands::TestEmitTestEventRequest::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.arg1 = params.arg1.unsignedCharValue;
            request.arg2 = static_cast<std::remove_reference_t<decltype(request.arg2)>>(params.arg2.unsignedCharValue);
            request.arg3 = params.arg3.boolValue;

            auto successFn = Callback<TestClusterClusterTestEmitTestEventResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)testEmitTestFabricScopedEventRequestWithParams:(MTRTestClusterClusterTestEmitTestFabricScopedEventRequestParams *)params
                                     completionHandler:
                                         (void (^)(
                                             MTRTestClusterClusterTestEmitTestFabricScopedEventResponseParams * _Nullable data,
                                             NSError * _Nullable error))completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    new MTRTestClusterClusterTestEmitTestFabricScopedEventResponseCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedInvokeTimeoutMs;
            ListFreer listFreer;
            TestCluster::Commands::TestEmitTestFabricScopedEventRequest::Type request;
            if (params != nil) {
                if (params.timedInvokeTimeoutMs != nil) {
                    timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
                }
            }
            request.arg1 = params.arg1.unsignedCharValue;

            auto successFn = Callback<TestClusterClusterTestEmitTestFabricScopedEventResponseCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.InvokeCommand(request, successFn->mContext, successFn->mCall, failureFn->mCall, timedInvokeTimeoutMs);
        });
}

- (void)readAttributeBooleanWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBooleanAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::Boolean::TypeInfo;
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeBooleanWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeBooleanWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeBooleanWithValue:(NSNumber * _Nonnull)value
                                params:(MTRWriteParams * _Nullable)params
                     completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::Boolean::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.boolValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeBooleanWithMinInterval:(NSNumber * _Nonnull)minInterval
                                     maxInterval:(NSNumber * _Nonnull)maxInterval
                                          params:(MTRSubscribeParams * _Nullable)params
                         subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                   reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRBooleanAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::Boolean::TypeInfo;
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRBooleanAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeBooleanWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                      endpoint:(NSNumber *)endpoint
                                         queue:(dispatch_queue_t)queue
                             completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBooleanAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TestCluster::Attributes::Boolean::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeBitmap8WithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRTestClusterBitmap8AttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::Bitmap8::TypeInfo;
            auto successFn = Callback<TestClusterBitmap8AttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeBitmap8WithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeBitmap8WithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeBitmap8WithValue:(NSNumber * _Nonnull)value
                                params:(MTRWriteParams * _Nullable)params
                     completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::Bitmap8::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = static_cast<std::remove_reference_t<decltype(cppValue)>>(value.unsignedCharValue);
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeBitmap8WithMinInterval:(NSNumber * _Nonnull)minInterval
                                     maxInterval:(NSNumber * _Nonnull)maxInterval
                                          params:(MTRSubscribeParams * _Nullable)params
                         subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                   reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRTestClusterBitmap8AttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::Bitmap8::TypeInfo;
            auto successFn = Callback<TestClusterBitmap8AttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRTestClusterBitmap8AttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeBitmap8WithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                      endpoint:(NSNumber *)endpoint
                                         queue:(dispatch_queue_t)queue
                             completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRTestClusterBitmap8AttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TestCluster::Attributes::Bitmap8::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<TestClusterBitmap8AttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeBitmap16WithCompletionHandler:(void (^)(
                                                       NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRTestClusterBitmap16AttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::Bitmap16::TypeInfo;
            auto successFn = Callback<TestClusterBitmap16AttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeBitmap16WithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeBitmap16WithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeBitmap16WithValue:(NSNumber * _Nonnull)value
                                 params:(MTRWriteParams * _Nullable)params
                      completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::Bitmap16::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = static_cast<std::remove_reference_t<decltype(cppValue)>>(value.unsignedShortValue);
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeBitmap16WithMinInterval:(NSNumber * _Nonnull)minInterval
                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                           params:(MTRSubscribeParams * _Nullable)params
                          subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRTestClusterBitmap16AttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::Bitmap16::TypeInfo;
            auto successFn = Callback<TestClusterBitmap16AttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRTestClusterBitmap16AttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeBitmap16WithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                       endpoint:(NSNumber *)endpoint
                                          queue:(dispatch_queue_t)queue
                              completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRTestClusterBitmap16AttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TestCluster::Attributes::Bitmap16::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<TestClusterBitmap16AttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeBitmap32WithCompletionHandler:(void (^)(
                                                       NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRTestClusterBitmap32AttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::Bitmap32::TypeInfo;
            auto successFn = Callback<TestClusterBitmap32AttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeBitmap32WithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeBitmap32WithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeBitmap32WithValue:(NSNumber * _Nonnull)value
                                 params:(MTRWriteParams * _Nullable)params
                      completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::Bitmap32::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = static_cast<std::remove_reference_t<decltype(cppValue)>>(value.unsignedIntValue);
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeBitmap32WithMinInterval:(NSNumber * _Nonnull)minInterval
                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                           params:(MTRSubscribeParams * _Nullable)params
                          subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRTestClusterBitmap32AttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::Bitmap32::TypeInfo;
            auto successFn = Callback<TestClusterBitmap32AttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRTestClusterBitmap32AttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeBitmap32WithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                       endpoint:(NSNumber *)endpoint
                                          queue:(dispatch_queue_t)queue
                              completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRTestClusterBitmap32AttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TestCluster::Attributes::Bitmap32::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<TestClusterBitmap32AttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeBitmap64WithCompletionHandler:(void (^)(
                                                       NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRTestClusterBitmap64AttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::Bitmap64::TypeInfo;
            auto successFn = Callback<TestClusterBitmap64AttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeBitmap64WithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeBitmap64WithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeBitmap64WithValue:(NSNumber * _Nonnull)value
                                 params:(MTRWriteParams * _Nullable)params
                      completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::Bitmap64::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = static_cast<std::remove_reference_t<decltype(cppValue)>>(value.unsignedLongLongValue);
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeBitmap64WithMinInterval:(NSNumber * _Nonnull)minInterval
                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                           params:(MTRSubscribeParams * _Nullable)params
                          subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRTestClusterBitmap64AttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::Bitmap64::TypeInfo;
            auto successFn = Callback<TestClusterBitmap64AttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRTestClusterBitmap64AttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeBitmap64WithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                       endpoint:(NSNumber *)endpoint
                                          queue:(dispatch_queue_t)queue
                              completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRTestClusterBitmap64AttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TestCluster::Attributes::Bitmap64::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<TestClusterBitmap64AttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeInt8uWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::Int8u::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeInt8uWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeInt8uWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeInt8uWithValue:(NSNumber * _Nonnull)value
                              params:(MTRWriteParams * _Nullable)params
                   completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::Int8u::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedCharValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeInt8uWithMinInterval:(NSNumber * _Nonnull)minInterval
                                   maxInterval:(NSNumber * _Nonnull)maxInterval
                                        params:(MTRSubscribeParams * _Nullable)params
                       subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::Int8u::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeInt8uWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                    endpoint:(NSNumber *)endpoint
                                       queue:(dispatch_queue_t)queue
                           completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TestCluster::Attributes::Int8u::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeInt16uWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::Int16u::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeInt16uWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeInt16uWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeInt16uWithValue:(NSNumber * _Nonnull)value
                               params:(MTRWriteParams * _Nullable)params
                    completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::Int16u::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeInt16uWithMinInterval:(NSNumber * _Nonnull)minInterval
                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                         params:(MTRSubscribeParams * _Nullable)params
                        subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::Int16u::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeInt16uWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                     endpoint:(NSNumber *)endpoint
                                        queue:(dispatch_queue_t)queue
                            completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TestCluster::Attributes::Int16u::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeInt24uWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::Int24u::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeInt24uWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeInt24uWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeInt24uWithValue:(NSNumber * _Nonnull)value
                               params:(MTRWriteParams * _Nullable)params
                    completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::Int24u::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedIntValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeInt24uWithMinInterval:(NSNumber * _Nonnull)minInterval
                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                         params:(MTRSubscribeParams * _Nullable)params
                        subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::Int24u::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeInt24uWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                     endpoint:(NSNumber *)endpoint
                                        queue:(dispatch_queue_t)queue
                            completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TestCluster::Attributes::Int24u::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeInt32uWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::Int32u::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeInt32uWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeInt32uWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeInt32uWithValue:(NSNumber * _Nonnull)value
                               params:(MTRWriteParams * _Nullable)params
                    completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::Int32u::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedIntValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeInt32uWithMinInterval:(NSNumber * _Nonnull)minInterval
                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                         params:(MTRSubscribeParams * _Nullable)params
                        subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::Int32u::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeInt32uWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                     endpoint:(NSNumber *)endpoint
                                        queue:(dispatch_queue_t)queue
                            completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TestCluster::Attributes::Int32u::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeInt40uWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt64uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::Int40u::TypeInfo;
            auto successFn = Callback<Int64uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeInt40uWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeInt40uWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeInt40uWithValue:(NSNumber * _Nonnull)value
                               params:(MTRWriteParams * _Nullable)params
                    completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::Int40u::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedLongLongValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeInt40uWithMinInterval:(NSNumber * _Nonnull)minInterval
                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                         params:(MTRSubscribeParams * _Nullable)params
                        subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt64uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::Int40u::TypeInfo;
            auto successFn = Callback<Int64uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt64uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeInt40uWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                     endpoint:(NSNumber *)endpoint
                                        queue:(dispatch_queue_t)queue
                            completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt64uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TestCluster::Attributes::Int40u::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int64uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeInt48uWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt64uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::Int48u::TypeInfo;
            auto successFn = Callback<Int64uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeInt48uWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeInt48uWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeInt48uWithValue:(NSNumber * _Nonnull)value
                               params:(MTRWriteParams * _Nullable)params
                    completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::Int48u::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedLongLongValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeInt48uWithMinInterval:(NSNumber * _Nonnull)minInterval
                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                         params:(MTRSubscribeParams * _Nullable)params
                        subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt64uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::Int48u::TypeInfo;
            auto successFn = Callback<Int64uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt64uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeInt48uWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                     endpoint:(NSNumber *)endpoint
                                        queue:(dispatch_queue_t)queue
                            completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt64uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TestCluster::Attributes::Int48u::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int64uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeInt56uWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt64uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::Int56u::TypeInfo;
            auto successFn = Callback<Int64uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeInt56uWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeInt56uWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeInt56uWithValue:(NSNumber * _Nonnull)value
                               params:(MTRWriteParams * _Nullable)params
                    completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::Int56u::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedLongLongValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeInt56uWithMinInterval:(NSNumber * _Nonnull)minInterval
                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                         params:(MTRSubscribeParams * _Nullable)params
                        subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt64uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::Int56u::TypeInfo;
            auto successFn = Callback<Int64uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt64uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeInt56uWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                     endpoint:(NSNumber *)endpoint
                                        queue:(dispatch_queue_t)queue
                            completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt64uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TestCluster::Attributes::Int56u::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int64uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeInt64uWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt64uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::Int64u::TypeInfo;
            auto successFn = Callback<Int64uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeInt64uWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeInt64uWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeInt64uWithValue:(NSNumber * _Nonnull)value
                               params:(MTRWriteParams * _Nullable)params
                    completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::Int64u::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedLongLongValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeInt64uWithMinInterval:(NSNumber * _Nonnull)minInterval
                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                         params:(MTRSubscribeParams * _Nullable)params
                        subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt64uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::Int64u::TypeInfo;
            auto successFn = Callback<Int64uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt64uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeInt64uWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                     endpoint:(NSNumber *)endpoint
                                        queue:(dispatch_queue_t)queue
                            completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt64uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TestCluster::Attributes::Int64u::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int64uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeInt8sWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::Int8s::TypeInfo;
            auto successFn = Callback<Int8sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeInt8sWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeInt8sWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeInt8sWithValue:(NSNumber * _Nonnull)value
                              params:(MTRWriteParams * _Nullable)params
                   completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::Int8s::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.charValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeInt8sWithMinInterval:(NSNumber * _Nonnull)minInterval
                                   maxInterval:(NSNumber * _Nonnull)maxInterval
                                        params:(MTRSubscribeParams * _Nullable)params
                       subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::Int8s::TypeInfo;
            auto successFn = Callback<Int8sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeInt8sWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                    endpoint:(NSNumber *)endpoint
                                       queue:(dispatch_queue_t)queue
                           completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TestCluster::Attributes::Int8s::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeInt16sWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::Int16s::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeInt16sWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeInt16sWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeInt16sWithValue:(NSNumber * _Nonnull)value
                               params:(MTRWriteParams * _Nullable)params
                    completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::Int16s::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.shortValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeInt16sWithMinInterval:(NSNumber * _Nonnull)minInterval
                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                         params:(MTRSubscribeParams * _Nullable)params
                        subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::Int16s::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeInt16sWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                     endpoint:(NSNumber *)endpoint
                                        queue:(dispatch_queue_t)queue
                            completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TestCluster::Attributes::Int16s::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeInt24sWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::Int24s::TypeInfo;
            auto successFn = Callback<Int32sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeInt24sWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeInt24sWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeInt24sWithValue:(NSNumber * _Nonnull)value
                               params:(MTRWriteParams * _Nullable)params
                    completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::Int24s::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.intValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeInt24sWithMinInterval:(NSNumber * _Nonnull)minInterval
                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                         params:(MTRSubscribeParams * _Nullable)params
                        subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::Int24s::TypeInfo;
            auto successFn = Callback<Int32sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeInt24sWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                     endpoint:(NSNumber *)endpoint
                                        queue:(dispatch_queue_t)queue
                            completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TestCluster::Attributes::Int24s::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeInt32sWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::Int32s::TypeInfo;
            auto successFn = Callback<Int32sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeInt32sWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeInt32sWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeInt32sWithValue:(NSNumber * _Nonnull)value
                               params:(MTRWriteParams * _Nullable)params
                    completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::Int32s::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.intValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeInt32sWithMinInterval:(NSNumber * _Nonnull)minInterval
                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                         params:(MTRSubscribeParams * _Nullable)params
                        subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::Int32s::TypeInfo;
            auto successFn = Callback<Int32sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeInt32sWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                     endpoint:(NSNumber *)endpoint
                                        queue:(dispatch_queue_t)queue
                            completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TestCluster::Attributes::Int32s::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeInt40sWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt64sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::Int40s::TypeInfo;
            auto successFn = Callback<Int64sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeInt40sWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeInt40sWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeInt40sWithValue:(NSNumber * _Nonnull)value
                               params:(MTRWriteParams * _Nullable)params
                    completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::Int40s::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.longLongValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeInt40sWithMinInterval:(NSNumber * _Nonnull)minInterval
                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                         params:(MTRSubscribeParams * _Nullable)params
                        subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt64sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::Int40s::TypeInfo;
            auto successFn = Callback<Int64sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt64sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeInt40sWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                     endpoint:(NSNumber *)endpoint
                                        queue:(dispatch_queue_t)queue
                            completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt64sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TestCluster::Attributes::Int40s::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int64sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeInt48sWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt64sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::Int48s::TypeInfo;
            auto successFn = Callback<Int64sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeInt48sWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeInt48sWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeInt48sWithValue:(NSNumber * _Nonnull)value
                               params:(MTRWriteParams * _Nullable)params
                    completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::Int48s::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.longLongValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeInt48sWithMinInterval:(NSNumber * _Nonnull)minInterval
                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                         params:(MTRSubscribeParams * _Nullable)params
                        subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt64sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::Int48s::TypeInfo;
            auto successFn = Callback<Int64sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt64sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeInt48sWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                     endpoint:(NSNumber *)endpoint
                                        queue:(dispatch_queue_t)queue
                            completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt64sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TestCluster::Attributes::Int48s::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int64sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeInt56sWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt64sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::Int56s::TypeInfo;
            auto successFn = Callback<Int64sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeInt56sWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeInt56sWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeInt56sWithValue:(NSNumber * _Nonnull)value
                               params:(MTRWriteParams * _Nullable)params
                    completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::Int56s::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.longLongValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeInt56sWithMinInterval:(NSNumber * _Nonnull)minInterval
                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                         params:(MTRSubscribeParams * _Nullable)params
                        subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt64sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::Int56s::TypeInfo;
            auto successFn = Callback<Int64sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt64sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeInt56sWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                     endpoint:(NSNumber *)endpoint
                                        queue:(dispatch_queue_t)queue
                            completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt64sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TestCluster::Attributes::Int56s::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int64sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeInt64sWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt64sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::Int64s::TypeInfo;
            auto successFn = Callback<Int64sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeInt64sWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeInt64sWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeInt64sWithValue:(NSNumber * _Nonnull)value
                               params:(MTRWriteParams * _Nullable)params
                    completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::Int64s::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.longLongValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeInt64sWithMinInterval:(NSNumber * _Nonnull)minInterval
                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                         params:(MTRSubscribeParams * _Nullable)params
                        subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt64sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::Int64s::TypeInfo;
            auto successFn = Callback<Int64sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt64sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeInt64sWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                     endpoint:(NSNumber *)endpoint
                                        queue:(dispatch_queue_t)queue
                            completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt64sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TestCluster::Attributes::Int64s::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int64sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeEnum8WithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::Enum8::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeEnum8WithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeEnum8WithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeEnum8WithValue:(NSNumber * _Nonnull)value
                              params:(MTRWriteParams * _Nullable)params
                   completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::Enum8::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedCharValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeEnum8WithMinInterval:(NSNumber * _Nonnull)minInterval
                                   maxInterval:(NSNumber * _Nonnull)maxInterval
                                        params:(MTRSubscribeParams * _Nullable)params
                       subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::Enum8::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeEnum8WithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                    endpoint:(NSNumber *)endpoint
                                       queue:(dispatch_queue_t)queue
                           completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TestCluster::Attributes::Enum8::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeEnum16WithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::Enum16::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeEnum16WithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeEnum16WithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeEnum16WithValue:(NSNumber * _Nonnull)value
                               params:(MTRWriteParams * _Nullable)params
                    completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::Enum16::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeEnum16WithMinInterval:(NSNumber * _Nonnull)minInterval
                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                         params:(MTRSubscribeParams * _Nullable)params
                        subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::Enum16::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeEnum16WithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                     endpoint:(NSNumber *)endpoint
                                        queue:(dispatch_queue_t)queue
                            completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TestCluster::Attributes::Enum16::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeFloatSingleWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRFloatAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::FloatSingle::TypeInfo;
            auto successFn = Callback<FloatAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeFloatSingleWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeFloatSingleWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeFloatSingleWithValue:(NSNumber * _Nonnull)value
                                    params:(MTRWriteParams * _Nullable)params
                         completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::FloatSingle::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.floatValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeFloatSingleWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRFloatAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::FloatSingle::TypeInfo;
            auto successFn = Callback<FloatAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRFloatAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeFloatSingleWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRFloatAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TestCluster::Attributes::FloatSingle::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<FloatAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeFloatDoubleWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRDoubleAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::FloatDouble::TypeInfo;
            auto successFn = Callback<DoubleAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeFloatDoubleWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeFloatDoubleWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeFloatDoubleWithValue:(NSNumber * _Nonnull)value
                                    params:(MTRWriteParams * _Nullable)params
                         completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::FloatDouble::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.doubleValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeFloatDoubleWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRDoubleAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::FloatDouble::TypeInfo;
            auto successFn = Callback<DoubleAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRDoubleAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeFloatDoubleWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRDoubleAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TestCluster::Attributes::FloatDouble::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<DoubleAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeOctetStringWithCompletionHandler:(void (^)(
                                                          NSData * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTROctetStringAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::OctetString::TypeInfo;
            auto successFn = Callback<OctetStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeOctetStringWithValue:(NSData * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeOctetStringWithValue:(NSData * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeOctetStringWithValue:(NSData * _Nonnull)value
                                    params:(MTRWriteParams * _Nullable)params
                         completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::OctetString::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = [self asByteSpan:value];
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeOctetStringWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSData * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTROctetStringAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::OctetString::TypeInfo;
            auto successFn = Callback<OctetStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTROctetStringAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeOctetStringWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:(void (^)(NSData * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTROctetStringAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TestCluster::Attributes::OctetString::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<OctetStringAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeListInt8uWithCompletionHandler:(void (^)(
                                                        NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRTestClusterListInt8uListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::ListInt8u::TypeInfo;
            auto successFn = Callback<TestClusterListInt8uListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeListInt8uWithValue:(NSArray * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeListInt8uWithValue:(NSArray * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeListInt8uWithValue:(NSArray * _Nonnull)value
                                  params:(MTRWriteParams * _Nullable)params
                       completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::ListInt8u::TypeInfo;
            TypeInfo::Type cppValue;
            {
                using ListType_0 = std::remove_reference_t<decltype(cppValue)>;
                using ListMemberType_0 = ListMemberTypeGetter<ListType_0>::Type;
                if (value.count != 0) {
                    auto * listHolder_0 = new ListHolder<ListMemberType_0>(value.count);
                    if (listHolder_0 == nullptr || listHolder_0->mList == nullptr) {
                        return CHIP_ERROR_INVALID_ARGUMENT;
                    }
                    listFreer.add(listHolder_0);
                    for (size_t i_0 = 0; i_0 < value.count; ++i_0) {
                        if (![value[i_0] isKindOfClass:[NSNumber class]]) {
                            // Wrong kind of value.
                            return CHIP_ERROR_INVALID_ARGUMENT;
                        }
                        auto element_0 = (NSNumber *) value[i_0];
                        listHolder_0->mList[i_0] = element_0.unsignedCharValue;
                    }
                    cppValue = ListType_0(listHolder_0->mList, value.count);
                } else {
                    cppValue = ListType_0();
                }
            }
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeListInt8uWithMinInterval:(NSNumber * _Nonnull)minInterval
                                       maxInterval:(NSNumber * _Nonnull)maxInterval
                                            params:(MTRSubscribeParams * _Nullable)params
                           subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                     reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRTestClusterListInt8uListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::ListInt8u::TypeInfo;
            auto successFn = Callback<TestClusterListInt8uListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRTestClusterListInt8uListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeListInt8uWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                        endpoint:(NSNumber *)endpoint
                                           queue:(dispatch_queue_t)queue
                               completionHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRTestClusterListInt8uListAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TestCluster::Attributes::ListInt8u::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<TestClusterListInt8uListAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeListOctetStringWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRTestClusterListOctetStringListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::ListOctetString::TypeInfo;
            auto successFn = Callback<TestClusterListOctetStringListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeListOctetStringWithValue:(NSArray * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeListOctetStringWithValue:(NSArray * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeListOctetStringWithValue:(NSArray * _Nonnull)value
                                        params:(MTRWriteParams * _Nullable)params
                             completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::ListOctetString::TypeInfo;
            TypeInfo::Type cppValue;
            {
                using ListType_0 = std::remove_reference_t<decltype(cppValue)>;
                using ListMemberType_0 = ListMemberTypeGetter<ListType_0>::Type;
                if (value.count != 0) {
                    auto * listHolder_0 = new ListHolder<ListMemberType_0>(value.count);
                    if (listHolder_0 == nullptr || listHolder_0->mList == nullptr) {
                        return CHIP_ERROR_INVALID_ARGUMENT;
                    }
                    listFreer.add(listHolder_0);
                    for (size_t i_0 = 0; i_0 < value.count; ++i_0) {
                        if (![value[i_0] isKindOfClass:[NSData class]]) {
                            // Wrong kind of value.
                            return CHIP_ERROR_INVALID_ARGUMENT;
                        }
                        auto element_0 = (NSData *) value[i_0];
                        listHolder_0->mList[i_0] = [self asByteSpan:element_0];
                    }
                    cppValue = ListType_0(listHolder_0->mList, value.count);
                } else {
                    cppValue = ListType_0();
                }
            }
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeListOctetStringWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRTestClusterListOctetStringListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::ListOctetString::TypeInfo;
            auto successFn = Callback<TestClusterListOctetStringListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRTestClusterListOctetStringListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeListOctetStringWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRTestClusterListOctetStringListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TestCluster::Attributes::ListOctetString::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<TestClusterListOctetStringListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeListStructOctetStringWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                    NSError * _Nullable error))completionHandler
{
    new MTRTestClusterListStructOctetStringListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::ListStructOctetString::TypeInfo;
            auto successFn = Callback<TestClusterListStructOctetStringListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeListStructOctetStringWithValue:(NSArray * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeListStructOctetStringWithValue:(NSArray * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeListStructOctetStringWithValue:(NSArray * _Nonnull)value
                                              params:(MTRWriteParams * _Nullable)params
                                   completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::ListStructOctetString::TypeInfo;
            TypeInfo::Type cppValue;
            {
                using ListType_0 = std::remove_reference_t<decltype(cppValue)>;
                using ListMemberType_0 = ListMemberTypeGetter<ListType_0>::Type;
                if (value.count != 0) {
                    auto * listHolder_0 = new ListHolder<ListMemberType_0>(value.count);
                    if (listHolder_0 == nullptr || listHolder_0->mList == nullptr) {
                        return CHIP_ERROR_INVALID_ARGUMENT;
                    }
                    listFreer.add(listHolder_0);
                    for (size_t i_0 = 0; i_0 < value.count; ++i_0) {
                        if (![value[i_0] isKindOfClass:[MTRTestClusterClusterTestListStructOctet class]]) {
                            // Wrong kind of value.
                            return CHIP_ERROR_INVALID_ARGUMENT;
                        }
                        auto element_0 = (MTRTestClusterClusterTestListStructOctet *) value[i_0];
                        listHolder_0->mList[i_0].member1 = element_0.member1.unsignedLongLongValue;
                        listHolder_0->mList[i_0].member2 = [self asByteSpan:element_0.member2];
                    }
                    cppValue = ListType_0(listHolder_0->mList, value.count);
                } else {
                    cppValue = ListType_0();
                }
            }
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeListStructOctetStringWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                   maxInterval:(NSNumber * _Nonnull)maxInterval
                                                        params:(MTRSubscribeParams * _Nullable)params
                                       subscriptionEstablished:
                                           (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                 reportHandler:
                                                     (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRTestClusterListStructOctetStringListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::ListStructOctetString::TypeInfo;
            auto successFn = Callback<TestClusterListStructOctetStringListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRTestClusterListStructOctetStringListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeListStructOctetStringWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                           completionHandler:
                                               (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRTestClusterListStructOctetStringListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TestCluster::Attributes::ListStructOctetString::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<TestClusterListStructOctetStringListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeLongOctetStringWithCompletionHandler:(void (^)(
                                                              NSData * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTROctetStringAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::LongOctetString::TypeInfo;
            auto successFn = Callback<OctetStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeLongOctetStringWithValue:(NSData * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeLongOctetStringWithValue:(NSData * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeLongOctetStringWithValue:(NSData * _Nonnull)value
                                        params:(MTRWriteParams * _Nullable)params
                             completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::LongOctetString::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = [self asByteSpan:value];
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeLongOctetStringWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSData * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTROctetStringAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::LongOctetString::TypeInfo;
            auto successFn = Callback<OctetStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTROctetStringAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeLongOctetStringWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSData * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTROctetStringAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TestCluster::Attributes::LongOctetString::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<OctetStringAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeCharStringWithCompletionHandler:(void (^)(
                                                         NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::CharString::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeCharStringWithValue:(NSString * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeCharStringWithValue:(NSString * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeCharStringWithValue:(NSString * _Nonnull)value
                                   params:(MTRWriteParams * _Nullable)params
                        completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::CharString::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = [self asCharSpan:value];
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeCharStringWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRCharStringAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::CharString::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRCharStringAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeCharStringWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TestCluster::Attributes::CharString::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeLongCharStringWithCompletionHandler:(void (^)(NSString * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::LongCharString::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeLongCharStringWithValue:(NSString * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeLongCharStringWithValue:(NSString * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeLongCharStringWithValue:(NSString * _Nonnull)value
                                       params:(MTRWriteParams * _Nullable)params
                            completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::LongCharString::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = [self asCharSpan:value];
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeLongCharStringWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRCharStringAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::LongCharString::TypeInfo;
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRCharStringAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeLongCharStringWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRCharStringAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TestCluster::Attributes::LongCharString::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<CharStringAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeEpochUsWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt64uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::EpochUs::TypeInfo;
            auto successFn = Callback<Int64uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeEpochUsWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeEpochUsWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeEpochUsWithValue:(NSNumber * _Nonnull)value
                                params:(MTRWriteParams * _Nullable)params
                     completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::EpochUs::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedLongLongValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeEpochUsWithMinInterval:(NSNumber * _Nonnull)minInterval
                                     maxInterval:(NSNumber * _Nonnull)maxInterval
                                          params:(MTRSubscribeParams * _Nullable)params
                         subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                   reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt64uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::EpochUs::TypeInfo;
            auto successFn = Callback<Int64uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt64uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeEpochUsWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                      endpoint:(NSNumber *)endpoint
                                         queue:(dispatch_queue_t)queue
                             completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt64uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TestCluster::Attributes::EpochUs::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int64uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeEpochSWithCompletionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::EpochS::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeEpochSWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeEpochSWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeEpochSWithValue:(NSNumber * _Nonnull)value
                               params:(MTRWriteParams * _Nullable)params
                    completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::EpochS::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedIntValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeEpochSWithMinInterval:(NSNumber * _Nonnull)minInterval
                                    maxInterval:(NSNumber * _Nonnull)maxInterval
                                         params:(MTRSubscribeParams * _Nullable)params
                        subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                  reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::EpochS::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeEpochSWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                     endpoint:(NSNumber *)endpoint
                                        queue:(dispatch_queue_t)queue
                            completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TestCluster::Attributes::EpochS::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeVendorIdWithCompletionHandler:(void (^)(
                                                       NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRVendorIdAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::VendorId::TypeInfo;
            auto successFn = Callback<VendorIdAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeVendorIdWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeVendorIdWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeVendorIdWithValue:(NSNumber * _Nonnull)value
                                 params:(MTRWriteParams * _Nullable)params
                      completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::VendorId::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = static_cast<std::remove_reference_t<decltype(cppValue)>>(value.unsignedShortValue);
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeVendorIdWithMinInterval:(NSNumber * _Nonnull)minInterval
                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                           params:(MTRSubscribeParams * _Nullable)params
                          subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRVendorIdAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::VendorId::TypeInfo;
            auto successFn = Callback<VendorIdAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRVendorIdAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeVendorIdWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                       endpoint:(NSNumber *)endpoint
                                          queue:(dispatch_queue_t)queue
                              completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRVendorIdAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TestCluster::Attributes::VendorId::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<VendorIdAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeListNullablesAndOptionalsStructWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                              NSError * _Nullable error))completionHandler
{
    new MTRTestClusterListNullablesAndOptionalsStructListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::ListNullablesAndOptionalsStruct::TypeInfo;
            auto successFn = Callback<TestClusterListNullablesAndOptionalsStructListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeListNullablesAndOptionalsStructWithValue:(NSArray * _Nonnull)value
                                             completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeListNullablesAndOptionalsStructWithValue:(NSArray * _Nonnull) value
                                                          params:nil
                                               completionHandler:completionHandler];
}
- (void)writeAttributeListNullablesAndOptionalsStructWithValue:(NSArray * _Nonnull)value
                                                        params:(MTRWriteParams * _Nullable)params
                                             completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::ListNullablesAndOptionalsStruct::TypeInfo;
            TypeInfo::Type cppValue;
            {
                using ListType_0 = std::remove_reference_t<decltype(cppValue)>;
                using ListMemberType_0 = ListMemberTypeGetter<ListType_0>::Type;
                if (value.count != 0) {
                    auto * listHolder_0 = new ListHolder<ListMemberType_0>(value.count);
                    if (listHolder_0 == nullptr || listHolder_0->mList == nullptr) {
                        return CHIP_ERROR_INVALID_ARGUMENT;
                    }
                    listFreer.add(listHolder_0);
                    for (size_t i_0 = 0; i_0 < value.count; ++i_0) {
                        if (![value[i_0] isKindOfClass:[MTRTestClusterClusterNullablesAndOptionalsStruct class]]) {
                            // Wrong kind of value.
                            return CHIP_ERROR_INVALID_ARGUMENT;
                        }
                        auto element_0 = (MTRTestClusterClusterNullablesAndOptionalsStruct *) value[i_0];
                        if (element_0.nullableInt == nil) {
                            listHolder_0->mList[i_0].nullableInt.SetNull();
                        } else {
                            auto & nonNullValue_2 = listHolder_0->mList[i_0].nullableInt.SetNonNull();
                            nonNullValue_2 = element_0.nullableInt.unsignedShortValue;
                        }
                        if (element_0.optionalInt != nil) {
                            auto & definedValue_2 = listHolder_0->mList[i_0].optionalInt.Emplace();
                            definedValue_2 = element_0.optionalInt.unsignedShortValue;
                        }
                        if (element_0.nullableOptionalInt != nil) {
                            auto & definedValue_2 = listHolder_0->mList[i_0].nullableOptionalInt.Emplace();
                            if (element_0.nullableOptionalInt == nil) {
                                definedValue_2.SetNull();
                            } else {
                                auto & nonNullValue_3 = definedValue_2.SetNonNull();
                                nonNullValue_3 = element_0.nullableOptionalInt.unsignedShortValue;
                            }
                        }
                        if (element_0.nullableString == nil) {
                            listHolder_0->mList[i_0].nullableString.SetNull();
                        } else {
                            auto & nonNullValue_2 = listHolder_0->mList[i_0].nullableString.SetNonNull();
                            nonNullValue_2 = [self asCharSpan:element_0.nullableString];
                        }
                        if (element_0.optionalString != nil) {
                            auto & definedValue_2 = listHolder_0->mList[i_0].optionalString.Emplace();
                            definedValue_2 = [self asCharSpan:element_0.optionalString];
                        }
                        if (element_0.nullableOptionalString != nil) {
                            auto & definedValue_2 = listHolder_0->mList[i_0].nullableOptionalString.Emplace();
                            if (element_0.nullableOptionalString == nil) {
                                definedValue_2.SetNull();
                            } else {
                                auto & nonNullValue_3 = definedValue_2.SetNonNull();
                                nonNullValue_3 = [self asCharSpan:element_0.nullableOptionalString];
                            }
                        }
                        if (element_0.nullableStruct == nil) {
                            listHolder_0->mList[i_0].nullableStruct.SetNull();
                        } else {
                            auto & nonNullValue_2 = listHolder_0->mList[i_0].nullableStruct.SetNonNull();
                            nonNullValue_2.a = element_0.nullableStruct.a.unsignedCharValue;
                            nonNullValue_2.b = element_0.nullableStruct.b.boolValue;
                            nonNullValue_2.c = static_cast<std::remove_reference_t<decltype(nonNullValue_2.c)>>(
                                element_0.nullableStruct.c.unsignedCharValue);
                            nonNullValue_2.d = [self asByteSpan:element_0.nullableStruct.d];
                            nonNullValue_2.e = [self asCharSpan:element_0.nullableStruct.e];
                            nonNullValue_2.f = static_cast<std::remove_reference_t<decltype(nonNullValue_2.f)>>(
                                element_0.nullableStruct.f.unsignedCharValue);
                            nonNullValue_2.g = element_0.nullableStruct.g.floatValue;
                            nonNullValue_2.h = element_0.nullableStruct.h.doubleValue;
                        }
                        if (element_0.optionalStruct != nil) {
                            auto & definedValue_2 = listHolder_0->mList[i_0].optionalStruct.Emplace();
                            definedValue_2.a = element_0.optionalStruct.a.unsignedCharValue;
                            definedValue_2.b = element_0.optionalStruct.b.boolValue;
                            definedValue_2.c = static_cast<std::remove_reference_t<decltype(definedValue_2.c)>>(
                                element_0.optionalStruct.c.unsignedCharValue);
                            definedValue_2.d = [self asByteSpan:element_0.optionalStruct.d];
                            definedValue_2.e = [self asCharSpan:element_0.optionalStruct.e];
                            definedValue_2.f = static_cast<std::remove_reference_t<decltype(definedValue_2.f)>>(
                                element_0.optionalStruct.f.unsignedCharValue);
                            definedValue_2.g = element_0.optionalStruct.g.floatValue;
                            definedValue_2.h = element_0.optionalStruct.h.doubleValue;
                        }
                        if (element_0.nullableOptionalStruct != nil) {
                            auto & definedValue_2 = listHolder_0->mList[i_0].nullableOptionalStruct.Emplace();
                            if (element_0.nullableOptionalStruct == nil) {
                                definedValue_2.SetNull();
                            } else {
                                auto & nonNullValue_3 = definedValue_2.SetNonNull();
                                nonNullValue_3.a = element_0.nullableOptionalStruct.a.unsignedCharValue;
                                nonNullValue_3.b = element_0.nullableOptionalStruct.b.boolValue;
                                nonNullValue_3.c = static_cast<std::remove_reference_t<decltype(nonNullValue_3.c)>>(
                                    element_0.nullableOptionalStruct.c.unsignedCharValue);
                                nonNullValue_3.d = [self asByteSpan:element_0.nullableOptionalStruct.d];
                                nonNullValue_3.e = [self asCharSpan:element_0.nullableOptionalStruct.e];
                                nonNullValue_3.f = static_cast<std::remove_reference_t<decltype(nonNullValue_3.f)>>(
                                    element_0.nullableOptionalStruct.f.unsignedCharValue);
                                nonNullValue_3.g = element_0.nullableOptionalStruct.g.floatValue;
                                nonNullValue_3.h = element_0.nullableOptionalStruct.h.doubleValue;
                            }
                        }
                        if (element_0.nullableList == nil) {
                            listHolder_0->mList[i_0].nullableList.SetNull();
                        } else {
                            auto & nonNullValue_2 = listHolder_0->mList[i_0].nullableList.SetNonNull();
                            {
                                using ListType_3 = std::remove_reference_t<decltype(nonNullValue_2)>;
                                using ListMemberType_3 = ListMemberTypeGetter<ListType_3>::Type;
                                if (element_0.nullableList.count != 0) {
                                    auto * listHolder_3 = new ListHolder<ListMemberType_3>(element_0.nullableList.count);
                                    if (listHolder_3 == nullptr || listHolder_3->mList == nullptr) {
                                        return CHIP_ERROR_INVALID_ARGUMENT;
                                    }
                                    listFreer.add(listHolder_3);
                                    for (size_t i_3 = 0; i_3 < element_0.nullableList.count; ++i_3) {
                                        if (![element_0.nullableList[i_3] isKindOfClass:[NSNumber class]]) {
                                            // Wrong kind of value.
                                            return CHIP_ERROR_INVALID_ARGUMENT;
                                        }
                                        auto element_3 = (NSNumber *) element_0.nullableList[i_3];
                                        listHolder_3->mList[i_3]
                                            = static_cast<std::remove_reference_t<decltype(listHolder_3->mList[i_3])>>(
                                                element_3.unsignedCharValue);
                                    }
                                    nonNullValue_2 = ListType_3(listHolder_3->mList, element_0.nullableList.count);
                                } else {
                                    nonNullValue_2 = ListType_3();
                                }
                            }
                        }
                        if (element_0.optionalList != nil) {
                            auto & definedValue_2 = listHolder_0->mList[i_0].optionalList.Emplace();
                            {
                                using ListType_3 = std::remove_reference_t<decltype(definedValue_2)>;
                                using ListMemberType_3 = ListMemberTypeGetter<ListType_3>::Type;
                                if (element_0.optionalList.count != 0) {
                                    auto * listHolder_3 = new ListHolder<ListMemberType_3>(element_0.optionalList.count);
                                    if (listHolder_3 == nullptr || listHolder_3->mList == nullptr) {
                                        return CHIP_ERROR_INVALID_ARGUMENT;
                                    }
                                    listFreer.add(listHolder_3);
                                    for (size_t i_3 = 0; i_3 < element_0.optionalList.count; ++i_3) {
                                        if (![element_0.optionalList[i_3] isKindOfClass:[NSNumber class]]) {
                                            // Wrong kind of value.
                                            return CHIP_ERROR_INVALID_ARGUMENT;
                                        }
                                        auto element_3 = (NSNumber *) element_0.optionalList[i_3];
                                        listHolder_3->mList[i_3]
                                            = static_cast<std::remove_reference_t<decltype(listHolder_3->mList[i_3])>>(
                                                element_3.unsignedCharValue);
                                    }
                                    definedValue_2 = ListType_3(listHolder_3->mList, element_0.optionalList.count);
                                } else {
                                    definedValue_2 = ListType_3();
                                }
                            }
                        }
                        if (element_0.nullableOptionalList != nil) {
                            auto & definedValue_2 = listHolder_0->mList[i_0].nullableOptionalList.Emplace();
                            if (element_0.nullableOptionalList == nil) {
                                definedValue_2.SetNull();
                            } else {
                                auto & nonNullValue_3 = definedValue_2.SetNonNull();
                                {
                                    using ListType_4 = std::remove_reference_t<decltype(nonNullValue_3)>;
                                    using ListMemberType_4 = ListMemberTypeGetter<ListType_4>::Type;
                                    if (element_0.nullableOptionalList.count != 0) {
                                        auto * listHolder_4
                                            = new ListHolder<ListMemberType_4>(element_0.nullableOptionalList.count);
                                        if (listHolder_4 == nullptr || listHolder_4->mList == nullptr) {
                                            return CHIP_ERROR_INVALID_ARGUMENT;
                                        }
                                        listFreer.add(listHolder_4);
                                        for (size_t i_4 = 0; i_4 < element_0.nullableOptionalList.count; ++i_4) {
                                            if (![element_0.nullableOptionalList[i_4] isKindOfClass:[NSNumber class]]) {
                                                // Wrong kind of value.
                                                return CHIP_ERROR_INVALID_ARGUMENT;
                                            }
                                            auto element_4 = (NSNumber *) element_0.nullableOptionalList[i_4];
                                            listHolder_4->mList[i_4]
                                                = static_cast<std::remove_reference_t<decltype(listHolder_4->mList[i_4])>>(
                                                    element_4.unsignedCharValue);
                                        }
                                        nonNullValue_3 = ListType_4(listHolder_4->mList, element_0.nullableOptionalList.count);
                                    } else {
                                        nonNullValue_3 = ListType_4();
                                    }
                                }
                            }
                        }
                    }
                    cppValue = ListType_0(listHolder_0->mList, value.count);
                } else {
                    cppValue = ListType_0();
                }
            }
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeListNullablesAndOptionalsStructWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                  params:(MTRSubscribeParams * _Nullable)params
                                                 subscriptionEstablished:
                                                     (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                           reportHandler:(void (^)(NSArray * _Nullable value,
                                                                             NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRTestClusterListNullablesAndOptionalsStructListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::ListNullablesAndOptionalsStruct::TypeInfo;
            auto successFn = Callback<TestClusterListNullablesAndOptionalsStructListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRTestClusterListNullablesAndOptionalsStructListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished,
                nil, params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeListNullablesAndOptionalsStructWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                              endpoint:(NSNumber *)endpoint
                                                                 queue:(dispatch_queue_t)queue
                                                     completionHandler:(void (^)(NSArray * _Nullable value,
                                                                           NSError * _Nullable error))completionHandler
{
    new MTRTestClusterListNullablesAndOptionalsStructListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TestCluster::Attributes::ListNullablesAndOptionalsStruct::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<TestClusterListNullablesAndOptionalsStructListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeEnumAttrWithCompletionHandler:(void (^)(
                                                       NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRTestClusterClusterSimpleEnumAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::EnumAttr::TypeInfo;
            auto successFn = Callback<TestClusterClusterSimpleEnumAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeEnumAttrWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeEnumAttrWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeEnumAttrWithValue:(NSNumber * _Nonnull)value
                                 params:(MTRWriteParams * _Nullable)params
                      completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::EnumAttr::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = static_cast<std::remove_reference_t<decltype(cppValue)>>(value.unsignedCharValue);
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeEnumAttrWithMinInterval:(NSNumber * _Nonnull)minInterval
                                      maxInterval:(NSNumber * _Nonnull)maxInterval
                                           params:(MTRSubscribeParams * _Nullable)params
                          subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                    reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRTestClusterClusterSimpleEnumAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::EnumAttr::TypeInfo;
            auto successFn = Callback<TestClusterClusterSimpleEnumAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRTestClusterClusterSimpleEnumAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeEnumAttrWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                       endpoint:(NSNumber *)endpoint
                                          queue:(dispatch_queue_t)queue
                              completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRTestClusterClusterSimpleEnumAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TestCluster::Attributes::EnumAttr::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<TestClusterClusterSimpleEnumAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeStructAttrWithCompletionHandler:(void (^)(MTRTestClusterClusterSimpleStruct * _Nullable value,
                                                         NSError * _Nullable error))completionHandler
{
    new MTRTestClusterStructAttrStructAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::StructAttr::TypeInfo;
            auto successFn = Callback<TestClusterStructAttrStructAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeStructAttrWithValue:(MTRTestClusterClusterSimpleStruct * _Nonnull)value
                        completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeStructAttrWithValue:(MTRTestClusterClusterSimpleStruct * _Nonnull) value
                                     params:nil
                          completionHandler:completionHandler];
}
- (void)writeAttributeStructAttrWithValue:(MTRTestClusterClusterSimpleStruct * _Nonnull)value
                                   params:(MTRWriteParams * _Nullable)params
                        completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::StructAttr::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue.a = value.a.unsignedCharValue;
            cppValue.b = value.b.boolValue;
            cppValue.c = static_cast<std::remove_reference_t<decltype(cppValue.c)>>(value.c.unsignedCharValue);
            cppValue.d = [self asByteSpan:value.d];
            cppValue.e = [self asCharSpan:value.e];
            cppValue.f = static_cast<std::remove_reference_t<decltype(cppValue.f)>>(value.f.unsignedCharValue);
            cppValue.g = value.g.floatValue;
            cppValue.h = value.h.doubleValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeStructAttrWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(MTRTestClusterClusterSimpleStruct * _Nullable value,
                                                        NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRTestClusterStructAttrStructAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::StructAttr::TypeInfo;
            auto successFn = Callback<TestClusterStructAttrStructAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRTestClusterStructAttrStructAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeStructAttrWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(MTRTestClusterClusterSimpleStruct * _Nullable value,
                                                      NSError * _Nullable error))completionHandler
{
    new MTRTestClusterStructAttrStructAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TestCluster::Attributes::StructAttr::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<TestClusterStructAttrStructAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeRangeRestrictedInt8uWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::RangeRestrictedInt8u::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeRangeRestrictedInt8uWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeRangeRestrictedInt8uWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeRangeRestrictedInt8uWithValue:(NSNumber * _Nonnull)value
                                             params:(MTRWriteParams * _Nullable)params
                                  completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::RangeRestrictedInt8u::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedCharValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeRangeRestrictedInt8uWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::RangeRestrictedInt8u::TypeInfo;
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeRangeRestrictedInt8uWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TestCluster::Attributes::RangeRestrictedInt8u::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeRangeRestrictedInt8sWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRInt8sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::RangeRestrictedInt8s::TypeInfo;
            auto successFn = Callback<Int8sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeRangeRestrictedInt8sWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeRangeRestrictedInt8sWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeRangeRestrictedInt8sWithValue:(NSNumber * _Nonnull)value
                                             params:(MTRWriteParams * _Nullable)params
                                  completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::RangeRestrictedInt8s::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.charValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeRangeRestrictedInt8sWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt8sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::RangeRestrictedInt8s::TypeInfo;
            auto successFn = Callback<Int8sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt8sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeRangeRestrictedInt8sWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt8sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TestCluster::Attributes::RangeRestrictedInt8s::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int8sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeRangeRestrictedInt16uWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                    NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::RangeRestrictedInt16u::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeRangeRestrictedInt16uWithValue:(NSNumber * _Nonnull)value
                                   completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeRangeRestrictedInt16uWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeRangeRestrictedInt16uWithValue:(NSNumber * _Nonnull)value
                                              params:(MTRWriteParams * _Nullable)params
                                   completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::RangeRestrictedInt16u::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.unsignedShortValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeRangeRestrictedInt16uWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                   maxInterval:(NSNumber * _Nonnull)maxInterval
                                                        params:(MTRSubscribeParams * _Nullable)params
                                       subscriptionEstablished:
                                           (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                 reportHandler:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::RangeRestrictedInt16u::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeRangeRestrictedInt16uWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                           completionHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TestCluster::Attributes::RangeRestrictedInt16u::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeRangeRestrictedInt16sWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                    NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::RangeRestrictedInt16s::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeRangeRestrictedInt16sWithValue:(NSNumber * _Nonnull)value
                                   completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeRangeRestrictedInt16sWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeRangeRestrictedInt16sWithValue:(NSNumber * _Nonnull)value
                                              params:(MTRWriteParams * _Nullable)params
                                   completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::RangeRestrictedInt16s::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.shortValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeRangeRestrictedInt16sWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                   maxInterval:(NSNumber * _Nonnull)maxInterval
                                                        params:(MTRSubscribeParams * _Nullable)params
                                       subscriptionEstablished:
                                           (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                 reportHandler:
                                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::RangeRestrictedInt16s::TypeInfo;
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeRangeRestrictedInt16sWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                    endpoint:(NSNumber *)endpoint
                                                       queue:(dispatch_queue_t)queue
                                           completionHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TestCluster::Attributes::RangeRestrictedInt16s::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeListLongOctetStringWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRTestClusterListLongOctetStringListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::ListLongOctetString::TypeInfo;
            auto successFn = Callback<TestClusterListLongOctetStringListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeListLongOctetStringWithValue:(NSArray * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeListLongOctetStringWithValue:(NSArray * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeListLongOctetStringWithValue:(NSArray * _Nonnull)value
                                            params:(MTRWriteParams * _Nullable)params
                                 completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::ListLongOctetString::TypeInfo;
            TypeInfo::Type cppValue;
            {
                using ListType_0 = std::remove_reference_t<decltype(cppValue)>;
                using ListMemberType_0 = ListMemberTypeGetter<ListType_0>::Type;
                if (value.count != 0) {
                    auto * listHolder_0 = new ListHolder<ListMemberType_0>(value.count);
                    if (listHolder_0 == nullptr || listHolder_0->mList == nullptr) {
                        return CHIP_ERROR_INVALID_ARGUMENT;
                    }
                    listFreer.add(listHolder_0);
                    for (size_t i_0 = 0; i_0 < value.count; ++i_0) {
                        if (![value[i_0] isKindOfClass:[NSData class]]) {
                            // Wrong kind of value.
                            return CHIP_ERROR_INVALID_ARGUMENT;
                        }
                        auto element_0 = (NSData *) value[i_0];
                        listHolder_0->mList[i_0] = [self asByteSpan:element_0];
                    }
                    cppValue = ListType_0(listHolder_0->mList, value.count);
                } else {
                    cppValue = ListType_0();
                }
            }
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeListLongOctetStringWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRTestClusterListLongOctetStringListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::ListLongOctetString::TypeInfo;
            auto successFn = Callback<TestClusterListLongOctetStringListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRTestClusterListLongOctetStringListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeListLongOctetStringWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRTestClusterListLongOctetStringListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TestCluster::Attributes::ListLongOctetString::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<TestClusterListLongOctetStringListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeListFabricScopedWithParams:(MTRReadParams * _Nullable)params
                              completionHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{ // Make a copy of params before we go async.
    params = [params copy];
    new MTRTestClusterListFabricScopedListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::ListFabricScoped::TypeInfo;
            auto successFn = Callback<TestClusterListFabricScopedListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue]);
        });
}

- (void)writeAttributeListFabricScopedWithValue:(NSArray * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeListFabricScopedWithValue:(NSArray * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeListFabricScopedWithValue:(NSArray * _Nonnull)value
                                         params:(MTRWriteParams * _Nullable)params
                              completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::ListFabricScoped::TypeInfo;
            TypeInfo::Type cppValue;
            {
                using ListType_0 = std::remove_reference_t<decltype(cppValue)>;
                using ListMemberType_0 = ListMemberTypeGetter<ListType_0>::Type;
                if (value.count != 0) {
                    auto * listHolder_0 = new ListHolder<ListMemberType_0>(value.count);
                    if (listHolder_0 == nullptr || listHolder_0->mList == nullptr) {
                        return CHIP_ERROR_INVALID_ARGUMENT;
                    }
                    listFreer.add(listHolder_0);
                    for (size_t i_0 = 0; i_0 < value.count; ++i_0) {
                        if (![value[i_0] isKindOfClass:[MTRTestClusterClusterTestFabricScoped class]]) {
                            // Wrong kind of value.
                            return CHIP_ERROR_INVALID_ARGUMENT;
                        }
                        auto element_0 = (MTRTestClusterClusterTestFabricScoped *) value[i_0];
                        listHolder_0->mList[i_0].fabricSensitiveInt8u = element_0.fabricSensitiveInt8u.unsignedCharValue;
                        if (element_0.optionalFabricSensitiveInt8u != nil) {
                            auto & definedValue_2 = listHolder_0->mList[i_0].optionalFabricSensitiveInt8u.Emplace();
                            definedValue_2 = element_0.optionalFabricSensitiveInt8u.unsignedCharValue;
                        }
                        if (element_0.nullableFabricSensitiveInt8u == nil) {
                            listHolder_0->mList[i_0].nullableFabricSensitiveInt8u.SetNull();
                        } else {
                            auto & nonNullValue_2 = listHolder_0->mList[i_0].nullableFabricSensitiveInt8u.SetNonNull();
                            nonNullValue_2 = element_0.nullableFabricSensitiveInt8u.unsignedCharValue;
                        }
                        if (element_0.nullableOptionalFabricSensitiveInt8u != nil) {
                            auto & definedValue_2 = listHolder_0->mList[i_0].nullableOptionalFabricSensitiveInt8u.Emplace();
                            if (element_0.nullableOptionalFabricSensitiveInt8u == nil) {
                                definedValue_2.SetNull();
                            } else {
                                auto & nonNullValue_3 = definedValue_2.SetNonNull();
                                nonNullValue_3 = element_0.nullableOptionalFabricSensitiveInt8u.unsignedCharValue;
                            }
                        }
                        listHolder_0->mList[i_0].fabricSensitiveCharString = [self asCharSpan:element_0.fabricSensitiveCharString];
                        listHolder_0->mList[i_0].fabricSensitiveStruct.a = element_0.fabricSensitiveStruct.a.unsignedCharValue;
                        listHolder_0->mList[i_0].fabricSensitiveStruct.b = element_0.fabricSensitiveStruct.b.boolValue;
                        listHolder_0->mList[i_0].fabricSensitiveStruct.c
                            = static_cast<std::remove_reference_t<decltype(listHolder_0->mList[i_0].fabricSensitiveStruct.c)>>(
                                element_0.fabricSensitiveStruct.c.unsignedCharValue);
                        listHolder_0->mList[i_0].fabricSensitiveStruct.d = [self asByteSpan:element_0.fabricSensitiveStruct.d];
                        listHolder_0->mList[i_0].fabricSensitiveStruct.e = [self asCharSpan:element_0.fabricSensitiveStruct.e];
                        listHolder_0->mList[i_0].fabricSensitiveStruct.f
                            = static_cast<std::remove_reference_t<decltype(listHolder_0->mList[i_0].fabricSensitiveStruct.f)>>(
                                element_0.fabricSensitiveStruct.f.unsignedCharValue);
                        listHolder_0->mList[i_0].fabricSensitiveStruct.g = element_0.fabricSensitiveStruct.g.floatValue;
                        listHolder_0->mList[i_0].fabricSensitiveStruct.h = element_0.fabricSensitiveStruct.h.doubleValue;
                        {
                            using ListType_2 = std::remove_reference_t<decltype(listHolder_0->mList[i_0].fabricSensitiveInt8uList)>;
                            using ListMemberType_2 = ListMemberTypeGetter<ListType_2>::Type;
                            if (element_0.fabricSensitiveInt8uList.count != 0) {
                                auto * listHolder_2 = new ListHolder<ListMemberType_2>(element_0.fabricSensitiveInt8uList.count);
                                if (listHolder_2 == nullptr || listHolder_2->mList == nullptr) {
                                    return CHIP_ERROR_INVALID_ARGUMENT;
                                }
                                listFreer.add(listHolder_2);
                                for (size_t i_2 = 0; i_2 < element_0.fabricSensitiveInt8uList.count; ++i_2) {
                                    if (![element_0.fabricSensitiveInt8uList[i_2] isKindOfClass:[NSNumber class]]) {
                                        // Wrong kind of value.
                                        return CHIP_ERROR_INVALID_ARGUMENT;
                                    }
                                    auto element_2 = (NSNumber *) element_0.fabricSensitiveInt8uList[i_2];
                                    listHolder_2->mList[i_2] = element_2.unsignedCharValue;
                                }
                                listHolder_0->mList[i_0].fabricSensitiveInt8uList
                                    = ListType_2(listHolder_2->mList, element_0.fabricSensitiveInt8uList.count);
                            } else {
                                listHolder_0->mList[i_0].fabricSensitiveInt8uList = ListType_2();
                            }
                        }
                        listHolder_0->mList[i_0].fabricIndex = element_0.fabricIndex.unsignedCharValue;
                    }
                    cppValue = ListType_0(listHolder_0->mList, value.count);
                } else {
                    cppValue = ListType_0();
                }
            }
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeListFabricScopedWithMinInterval:(NSNumber * _Nonnull)minInterval
                                              maxInterval:(NSNumber * _Nonnull)maxInterval
                                                   params:(MTRSubscribeParams * _Nullable)params
                                  subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                            reportHandler:
                                                (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRTestClusterListFabricScopedListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::ListFabricScoped::TypeInfo;
            auto successFn = Callback<TestClusterListFabricScopedListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRTestClusterListFabricScopedListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeListFabricScopedWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRTestClusterListFabricScopedListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TestCluster::Attributes::ListFabricScoped::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<TestClusterListFabricScopedListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeTimedWriteBooleanWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                NSError * _Nullable error))completionHandler
{
    new MTRBooleanAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::TimedWriteBoolean::TypeInfo;
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeTimedWriteBooleanWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeTimedWriteBooleanWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeTimedWriteBooleanWithValue:(NSNumber * _Nonnull)value
                                          params:(MTRWriteParams * _Nullable)params
                               completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::TimedWriteBoolean::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.boolValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeTimedWriteBooleanWithMinInterval:(NSNumber * _Nonnull)minInterval
                                               maxInterval:(NSNumber * _Nonnull)maxInterval
                                                    params:(MTRSubscribeParams * _Nullable)params
                                   subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                             reportHandler:
                                                 (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRBooleanAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::TimedWriteBoolean::TypeInfo;
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRBooleanAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeTimedWriteBooleanWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                endpoint:(NSNumber *)endpoint
                                                   queue:(dispatch_queue_t)queue
                                       completionHandler:
                                           (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBooleanAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TestCluster::Attributes::TimedWriteBoolean::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeGeneralErrorBooleanWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRBooleanAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::GeneralErrorBoolean::TypeInfo;
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeGeneralErrorBooleanWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeGeneralErrorBooleanWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeGeneralErrorBooleanWithValue:(NSNumber * _Nonnull)value
                                            params:(MTRWriteParams * _Nullable)params
                                 completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::GeneralErrorBoolean::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.boolValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeGeneralErrorBooleanWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRBooleanAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::GeneralErrorBoolean::TypeInfo;
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRBooleanAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeGeneralErrorBooleanWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBooleanAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TestCluster::Attributes::GeneralErrorBoolean::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeClusterErrorBooleanWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRBooleanAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::ClusterErrorBoolean::TypeInfo;
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeClusterErrorBooleanWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeClusterErrorBooleanWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeClusterErrorBooleanWithValue:(NSNumber * _Nonnull)value
                                            params:(MTRWriteParams * _Nullable)params
                                 completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::ClusterErrorBoolean::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.boolValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeClusterErrorBooleanWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRBooleanAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::ClusterErrorBoolean::TypeInfo;
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRBooleanAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeClusterErrorBooleanWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBooleanAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TestCluster::Attributes::ClusterErrorBoolean::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeUnsupportedWithCompletionHandler:(void (^)(
                                                          NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBooleanAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::Unsupported::TypeInfo;
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeUnsupportedWithValue:(NSNumber * _Nonnull)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeUnsupportedWithValue:(NSNumber * _Nonnull) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeUnsupportedWithValue:(NSNumber * _Nonnull)value
                                    params:(MTRWriteParams * _Nullable)params
                         completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::Unsupported::TypeInfo;
            TypeInfo::Type cppValue;
            cppValue = value.boolValue;
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeUnsupportedWithMinInterval:(NSNumber * _Nonnull)minInterval
                                         maxInterval:(NSNumber * _Nonnull)maxInterval
                                              params:(MTRSubscribeParams * _Nullable)params
                             subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                       reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRBooleanAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::Unsupported::TypeInfo;
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRBooleanAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeUnsupportedWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                          endpoint:(NSNumber *)endpoint
                                             queue:(dispatch_queue_t)queue
                                 completionHandler:
                                     (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRBooleanAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TestCluster::Attributes::Unsupported::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<BooleanAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeNullableBooleanWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRNullableBooleanAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::NullableBoolean::TypeInfo;
            auto successFn = Callback<NullableBooleanAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeNullableBooleanWithValue:(NSNumber * _Nullable)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeNullableBooleanWithValue:(NSNumber * _Nullable) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeNullableBooleanWithValue:(NSNumber * _Nullable)value
                                        params:(MTRWriteParams * _Nullable)params
                             completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::NullableBoolean::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.boolValue;
            }
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeNullableBooleanWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableBooleanAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::NullableBoolean::TypeInfo;
            auto successFn = Callback<NullableBooleanAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableBooleanAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeNullableBooleanWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableBooleanAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TestCluster::Attributes::NullableBoolean::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableBooleanAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeNullableBitmap8WithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRTestClusterNullableBitmap8AttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::NullableBitmap8::TypeInfo;
            auto successFn = Callback<TestClusterNullableBitmap8AttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeNullableBitmap8WithValue:(NSNumber * _Nullable)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeNullableBitmap8WithValue:(NSNumber * _Nullable) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeNullableBitmap8WithValue:(NSNumber * _Nullable)value
                                        params:(MTRWriteParams * _Nullable)params
                             completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::NullableBitmap8::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = static_cast<std::remove_reference_t<decltype(nonNullValue_0)>>(value.unsignedCharValue);
            }
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeNullableBitmap8WithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRTestClusterNullableBitmap8AttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::NullableBitmap8::TypeInfo;
            auto successFn = Callback<TestClusterNullableBitmap8AttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRTestClusterNullableBitmap8AttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeNullableBitmap8WithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRTestClusterNullableBitmap8AttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TestCluster::Attributes::NullableBitmap8::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<TestClusterNullableBitmap8AttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeNullableBitmap16WithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    new MTRTestClusterNullableBitmap16AttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::NullableBitmap16::TypeInfo;
            auto successFn = Callback<TestClusterNullableBitmap16AttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeNullableBitmap16WithValue:(NSNumber * _Nullable)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeNullableBitmap16WithValue:(NSNumber * _Nullable) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeNullableBitmap16WithValue:(NSNumber * _Nullable)value
                                         params:(MTRWriteParams * _Nullable)params
                              completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::NullableBitmap16::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = static_cast<std::remove_reference_t<decltype(nonNullValue_0)>>(value.unsignedShortValue);
            }
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeNullableBitmap16WithMinInterval:(NSNumber * _Nonnull)minInterval
                                              maxInterval:(NSNumber * _Nonnull)maxInterval
                                                   params:(MTRSubscribeParams * _Nullable)params
                                  subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                            reportHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRTestClusterNullableBitmap16AttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::NullableBitmap16::TypeInfo;
            auto successFn = Callback<TestClusterNullableBitmap16AttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRTestClusterNullableBitmap16AttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeNullableBitmap16WithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRTestClusterNullableBitmap16AttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TestCluster::Attributes::NullableBitmap16::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<TestClusterNullableBitmap16AttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeNullableBitmap32WithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    new MTRTestClusterNullableBitmap32AttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::NullableBitmap32::TypeInfo;
            auto successFn = Callback<TestClusterNullableBitmap32AttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeNullableBitmap32WithValue:(NSNumber * _Nullable)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeNullableBitmap32WithValue:(NSNumber * _Nullable) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeNullableBitmap32WithValue:(NSNumber * _Nullable)value
                                         params:(MTRWriteParams * _Nullable)params
                              completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::NullableBitmap32::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = static_cast<std::remove_reference_t<decltype(nonNullValue_0)>>(value.unsignedIntValue);
            }
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeNullableBitmap32WithMinInterval:(NSNumber * _Nonnull)minInterval
                                              maxInterval:(NSNumber * _Nonnull)maxInterval
                                                   params:(MTRSubscribeParams * _Nullable)params
                                  subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                            reportHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRTestClusterNullableBitmap32AttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::NullableBitmap32::TypeInfo;
            auto successFn = Callback<TestClusterNullableBitmap32AttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRTestClusterNullableBitmap32AttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeNullableBitmap32WithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRTestClusterNullableBitmap32AttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TestCluster::Attributes::NullableBitmap32::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<TestClusterNullableBitmap32AttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeNullableBitmap64WithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    new MTRTestClusterNullableBitmap64AttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::NullableBitmap64::TypeInfo;
            auto successFn = Callback<TestClusterNullableBitmap64AttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeNullableBitmap64WithValue:(NSNumber * _Nullable)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeNullableBitmap64WithValue:(NSNumber * _Nullable) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeNullableBitmap64WithValue:(NSNumber * _Nullable)value
                                         params:(MTRWriteParams * _Nullable)params
                              completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::NullableBitmap64::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = static_cast<std::remove_reference_t<decltype(nonNullValue_0)>>(value.unsignedLongLongValue);
            }
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeNullableBitmap64WithMinInterval:(NSNumber * _Nonnull)minInterval
                                              maxInterval:(NSNumber * _Nonnull)maxInterval
                                                   params:(MTRSubscribeParams * _Nullable)params
                                  subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                            reportHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRTestClusterNullableBitmap64AttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::NullableBitmap64::TypeInfo;
            auto successFn = Callback<TestClusterNullableBitmap64AttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRTestClusterNullableBitmap64AttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeNullableBitmap64WithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRTestClusterNullableBitmap64AttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TestCluster::Attributes::NullableBitmap64::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<TestClusterNullableBitmap64AttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeNullableInt8uWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::NullableInt8u::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeNullableInt8uWithValue:(NSNumber * _Nullable)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeNullableInt8uWithValue:(NSNumber * _Nullable) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeNullableInt8uWithValue:(NSNumber * _Nullable)value
                                      params:(MTRWriteParams * _Nullable)params
                           completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::NullableInt8u::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.unsignedCharValue;
            }
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeNullableInt8uWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::NullableInt8u::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeNullableInt8uWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TestCluster::Attributes::NullableInt8u::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeNullableInt16uWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::NullableInt16u::TypeInfo;
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeNullableInt16uWithValue:(NSNumber * _Nullable)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeNullableInt16uWithValue:(NSNumber * _Nullable) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeNullableInt16uWithValue:(NSNumber * _Nullable)value
                                       params:(MTRWriteParams * _Nullable)params
                            completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::NullableInt16u::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.unsignedShortValue;
            }
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeNullableInt16uWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::NullableInt16u::TypeInfo;
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeNullableInt16uWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TestCluster::Attributes::NullableInt16u::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeNullableInt24uWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    new MTRNullableInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::NullableInt24u::TypeInfo;
            auto successFn = Callback<NullableInt32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeNullableInt24uWithValue:(NSNumber * _Nullable)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeNullableInt24uWithValue:(NSNumber * _Nullable) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeNullableInt24uWithValue:(NSNumber * _Nullable)value
                                       params:(MTRWriteParams * _Nullable)params
                            completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::NullableInt24u::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.unsignedIntValue;
            }
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeNullableInt24uWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::NullableInt24u::TypeInfo;
            auto successFn = Callback<NullableInt32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeNullableInt24uWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TestCluster::Attributes::NullableInt24u::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeNullableInt32uWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    new MTRNullableInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::NullableInt32u::TypeInfo;
            auto successFn = Callback<NullableInt32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeNullableInt32uWithValue:(NSNumber * _Nullable)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeNullableInt32uWithValue:(NSNumber * _Nullable) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeNullableInt32uWithValue:(NSNumber * _Nullable)value
                                       params:(MTRWriteParams * _Nullable)params
                            completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::NullableInt32u::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.unsignedIntValue;
            }
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeNullableInt32uWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::NullableInt32u::TypeInfo;
            auto successFn = Callback<NullableInt32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeNullableInt32uWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TestCluster::Attributes::NullableInt32u::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeNullableInt40uWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    new MTRNullableInt64uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::NullableInt40u::TypeInfo;
            auto successFn = Callback<NullableInt64uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeNullableInt40uWithValue:(NSNumber * _Nullable)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeNullableInt40uWithValue:(NSNumber * _Nullable) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeNullableInt40uWithValue:(NSNumber * _Nullable)value
                                       params:(MTRWriteParams * _Nullable)params
                            completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::NullableInt40u::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.unsignedLongLongValue;
            }
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeNullableInt40uWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt64uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::NullableInt40u::TypeInfo;
            auto successFn = Callback<NullableInt64uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt64uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeNullableInt40uWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt64uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TestCluster::Attributes::NullableInt40u::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt64uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeNullableInt48uWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    new MTRNullableInt64uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::NullableInt48u::TypeInfo;
            auto successFn = Callback<NullableInt64uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeNullableInt48uWithValue:(NSNumber * _Nullable)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeNullableInt48uWithValue:(NSNumber * _Nullable) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeNullableInt48uWithValue:(NSNumber * _Nullable)value
                                       params:(MTRWriteParams * _Nullable)params
                            completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::NullableInt48u::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.unsignedLongLongValue;
            }
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeNullableInt48uWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt64uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::NullableInt48u::TypeInfo;
            auto successFn = Callback<NullableInt64uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt64uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeNullableInt48uWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt64uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TestCluster::Attributes::NullableInt48u::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt64uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeNullableInt56uWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    new MTRNullableInt64uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::NullableInt56u::TypeInfo;
            auto successFn = Callback<NullableInt64uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeNullableInt56uWithValue:(NSNumber * _Nullable)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeNullableInt56uWithValue:(NSNumber * _Nullable) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeNullableInt56uWithValue:(NSNumber * _Nullable)value
                                       params:(MTRWriteParams * _Nullable)params
                            completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::NullableInt56u::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.unsignedLongLongValue;
            }
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeNullableInt56uWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt64uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::NullableInt56u::TypeInfo;
            auto successFn = Callback<NullableInt64uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt64uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeNullableInt56uWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt64uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TestCluster::Attributes::NullableInt56u::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt64uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeNullableInt64uWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    new MTRNullableInt64uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::NullableInt64u::TypeInfo;
            auto successFn = Callback<NullableInt64uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeNullableInt64uWithValue:(NSNumber * _Nullable)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeNullableInt64uWithValue:(NSNumber * _Nullable) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeNullableInt64uWithValue:(NSNumber * _Nullable)value
                                       params:(MTRWriteParams * _Nullable)params
                            completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::NullableInt64u::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.unsignedLongLongValue;
            }
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeNullableInt64uWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt64uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::NullableInt64u::TypeInfo;
            auto successFn = Callback<NullableInt64uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt64uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeNullableInt64uWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt64uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TestCluster::Attributes::NullableInt64u::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt64uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeNullableInt8sWithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::NullableInt8s::TypeInfo;
            auto successFn = Callback<NullableInt8sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeNullableInt8sWithValue:(NSNumber * _Nullable)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeNullableInt8sWithValue:(NSNumber * _Nullable) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeNullableInt8sWithValue:(NSNumber * _Nullable)value
                                      params:(MTRWriteParams * _Nullable)params
                           completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::NullableInt8s::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.charValue;
            }
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeNullableInt8sWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt8sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::NullableInt8s::TypeInfo;
            auto successFn = Callback<NullableInt8sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt8sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeNullableInt8sWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TestCluster::Attributes::NullableInt8s::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt8sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeNullableInt16sWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::NullableInt16s::TypeInfo;
            auto successFn = Callback<NullableInt16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeNullableInt16sWithValue:(NSNumber * _Nullable)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeNullableInt16sWithValue:(NSNumber * _Nullable) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeNullableInt16sWithValue:(NSNumber * _Nullable)value
                                       params:(MTRWriteParams * _Nullable)params
                            completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::NullableInt16s::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.shortValue;
            }
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeNullableInt16sWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::NullableInt16s::TypeInfo;
            auto successFn = Callback<NullableInt16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeNullableInt16sWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TestCluster::Attributes::NullableInt16s::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeNullableInt24sWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    new MTRNullableInt32sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::NullableInt24s::TypeInfo;
            auto successFn = Callback<NullableInt32sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeNullableInt24sWithValue:(NSNumber * _Nullable)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeNullableInt24sWithValue:(NSNumber * _Nullable) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeNullableInt24sWithValue:(NSNumber * _Nullable)value
                                       params:(MTRWriteParams * _Nullable)params
                            completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::NullableInt24s::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.intValue;
            }
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeNullableInt24sWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt32sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::NullableInt24s::TypeInfo;
            auto successFn = Callback<NullableInt32sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt32sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeNullableInt24sWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt32sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TestCluster::Attributes::NullableInt24s::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt32sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeNullableInt32sWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    new MTRNullableInt32sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::NullableInt32s::TypeInfo;
            auto successFn = Callback<NullableInt32sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeNullableInt32sWithValue:(NSNumber * _Nullable)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeNullableInt32sWithValue:(NSNumber * _Nullable) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeNullableInt32sWithValue:(NSNumber * _Nullable)value
                                       params:(MTRWriteParams * _Nullable)params
                            completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::NullableInt32s::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.intValue;
            }
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeNullableInt32sWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt32sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::NullableInt32s::TypeInfo;
            auto successFn = Callback<NullableInt32sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt32sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeNullableInt32sWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt32sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TestCluster::Attributes::NullableInt32s::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt32sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeNullableInt40sWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    new MTRNullableInt64sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::NullableInt40s::TypeInfo;
            auto successFn = Callback<NullableInt64sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeNullableInt40sWithValue:(NSNumber * _Nullable)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeNullableInt40sWithValue:(NSNumber * _Nullable) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeNullableInt40sWithValue:(NSNumber * _Nullable)value
                                       params:(MTRWriteParams * _Nullable)params
                            completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::NullableInt40s::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.longLongValue;
            }
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeNullableInt40sWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt64sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::NullableInt40s::TypeInfo;
            auto successFn = Callback<NullableInt64sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt64sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeNullableInt40sWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt64sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TestCluster::Attributes::NullableInt40s::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt64sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeNullableInt48sWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    new MTRNullableInt64sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::NullableInt48s::TypeInfo;
            auto successFn = Callback<NullableInt64sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeNullableInt48sWithValue:(NSNumber * _Nullable)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeNullableInt48sWithValue:(NSNumber * _Nullable) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeNullableInt48sWithValue:(NSNumber * _Nullable)value
                                       params:(MTRWriteParams * _Nullable)params
                            completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::NullableInt48s::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.longLongValue;
            }
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeNullableInt48sWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt64sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::NullableInt48s::TypeInfo;
            auto successFn = Callback<NullableInt64sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt64sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeNullableInt48sWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt64sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TestCluster::Attributes::NullableInt48s::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt64sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeNullableInt56sWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    new MTRNullableInt64sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::NullableInt56s::TypeInfo;
            auto successFn = Callback<NullableInt64sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeNullableInt56sWithValue:(NSNumber * _Nullable)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeNullableInt56sWithValue:(NSNumber * _Nullable) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeNullableInt56sWithValue:(NSNumber * _Nullable)value
                                       params:(MTRWriteParams * _Nullable)params
                            completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::NullableInt56s::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.longLongValue;
            }
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeNullableInt56sWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt64sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::NullableInt56s::TypeInfo;
            auto successFn = Callback<NullableInt64sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt64sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeNullableInt56sWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt64sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TestCluster::Attributes::NullableInt56s::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt64sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeNullableInt64sWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    new MTRNullableInt64sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::NullableInt64s::TypeInfo;
            auto successFn = Callback<NullableInt64sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeNullableInt64sWithValue:(NSNumber * _Nullable)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeNullableInt64sWithValue:(NSNumber * _Nullable) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeNullableInt64sWithValue:(NSNumber * _Nullable)value
                                       params:(MTRWriteParams * _Nullable)params
                            completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::NullableInt64s::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.longLongValue;
            }
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeNullableInt64sWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt64sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::NullableInt64s::TypeInfo;
            auto successFn = Callback<NullableInt64sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt64sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeNullableInt64sWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt64sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TestCluster::Attributes::NullableInt64s::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt64sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeNullableEnum8WithCompletionHandler:(void (^)(
                                                            NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::NullableEnum8::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeNullableEnum8WithValue:(NSNumber * _Nullable)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeNullableEnum8WithValue:(NSNumber * _Nullable) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeNullableEnum8WithValue:(NSNumber * _Nullable)value
                                      params:(MTRWriteParams * _Nullable)params
                           completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::NullableEnum8::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.unsignedCharValue;
            }
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeNullableEnum8WithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::NullableEnum8::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeNullableEnum8WithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TestCluster::Attributes::NullableEnum8::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeNullableEnum16WithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::NullableEnum16::TypeInfo;
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeNullableEnum16WithValue:(NSNumber * _Nullable)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeNullableEnum16WithValue:(NSNumber * _Nullable) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeNullableEnum16WithValue:(NSNumber * _Nullable)value
                                       params:(MTRWriteParams * _Nullable)params
                            completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::NullableEnum16::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.unsignedShortValue;
            }
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeNullableEnum16WithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:
                                              (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::NullableEnum16::TypeInfo;
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeNullableEnum16WithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:
                                        (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TestCluster::Attributes::NullableEnum16::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeNullableFloatSingleWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRNullableFloatAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::NullableFloatSingle::TypeInfo;
            auto successFn = Callback<NullableFloatAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeNullableFloatSingleWithValue:(NSNumber * _Nullable)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeNullableFloatSingleWithValue:(NSNumber * _Nullable) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeNullableFloatSingleWithValue:(NSNumber * _Nullable)value
                                            params:(MTRWriteParams * _Nullable)params
                                 completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::NullableFloatSingle::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.floatValue;
            }
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeNullableFloatSingleWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableFloatAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::NullableFloatSingle::TypeInfo;
            auto successFn = Callback<NullableFloatAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableFloatAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeNullableFloatSingleWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableFloatAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TestCluster::Attributes::NullableFloatSingle::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableFloatAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeNullableFloatDoubleWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRNullableDoubleAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::NullableFloatDouble::TypeInfo;
            auto successFn = Callback<NullableDoubleAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeNullableFloatDoubleWithValue:(NSNumber * _Nullable)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeNullableFloatDoubleWithValue:(NSNumber * _Nullable) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeNullableFloatDoubleWithValue:(NSNumber * _Nullable)value
                                            params:(MTRWriteParams * _Nullable)params
                                 completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::NullableFloatDouble::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.doubleValue;
            }
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeNullableFloatDoubleWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableDoubleAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::NullableFloatDouble::TypeInfo;
            auto successFn = Callback<NullableDoubleAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableDoubleAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeNullableFloatDoubleWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableDoubleAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TestCluster::Attributes::NullableFloatDouble::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableDoubleAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeNullableOctetStringWithCompletionHandler:(void (^)(NSData * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRNullableOctetStringAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::NullableOctetString::TypeInfo;
            auto successFn = Callback<NullableOctetStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeNullableOctetStringWithValue:(NSData * _Nullable)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeNullableOctetStringWithValue:(NSData * _Nullable) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeNullableOctetStringWithValue:(NSData * _Nullable)value
                                            params:(MTRWriteParams * _Nullable)params
                                 completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::NullableOctetString::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = [self asByteSpan:value];
            }
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeNullableOctetStringWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSData * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableOctetStringAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::NullableOctetString::TypeInfo;
            auto successFn = Callback<NullableOctetStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableOctetStringAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeNullableOctetStringWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSData * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableOctetStringAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TestCluster::Attributes::NullableOctetString::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableOctetStringAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeNullableCharStringWithCompletionHandler:(void (^)(NSString * _Nullable value,
                                                                 NSError * _Nullable error))completionHandler
{
    new MTRNullableCharStringAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::NullableCharString::TypeInfo;
            auto successFn = Callback<NullableCharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeNullableCharStringWithValue:(NSString * _Nullable)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeNullableCharStringWithValue:(NSString * _Nullable) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeNullableCharStringWithValue:(NSString * _Nullable)value
                                           params:(MTRWriteParams * _Nullable)params
                                completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::NullableCharString::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = [self asCharSpan:value];
            }
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeNullableCharStringWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                maxInterval:(NSNumber * _Nonnull)maxInterval
                                                     params:(MTRSubscribeParams * _Nullable)params
                                    subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                              reportHandler:
                                                  (void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableCharStringAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::NullableCharString::TypeInfo;
            auto successFn = Callback<NullableCharStringAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableCharStringAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeNullableCharStringWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                 endpoint:(NSNumber *)endpoint
                                                    queue:(dispatch_queue_t)queue
                                        completionHandler:
                                            (void (^)(NSString * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableCharStringAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TestCluster::Attributes::NullableCharString::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableCharStringAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeNullableEnumAttrWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                               NSError * _Nullable error))completionHandler
{
    new MTRNullableTestClusterClusterSimpleEnumAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::NullableEnumAttr::TypeInfo;
            auto successFn = Callback<NullableTestClusterClusterSimpleEnumAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeNullableEnumAttrWithValue:(NSNumber * _Nullable)value completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeNullableEnumAttrWithValue:(NSNumber * _Nullable) value params:nil completionHandler:completionHandler];
}
- (void)writeAttributeNullableEnumAttrWithValue:(NSNumber * _Nullable)value
                                         params:(MTRWriteParams * _Nullable)params
                              completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::NullableEnumAttr::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = static_cast<std::remove_reference_t<decltype(nonNullValue_0)>>(value.unsignedCharValue);
            }
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeNullableEnumAttrWithMinInterval:(NSNumber * _Nonnull)minInterval
                                              maxInterval:(NSNumber * _Nonnull)maxInterval
                                                   params:(MTRSubscribeParams * _Nullable)params
                                  subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                            reportHandler:
                                                (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableTestClusterClusterSimpleEnumAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::NullableEnumAttr::TypeInfo;
            auto successFn = Callback<NullableTestClusterClusterSimpleEnumAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableTestClusterClusterSimpleEnumAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeNullableEnumAttrWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                               endpoint:(NSNumber *)endpoint
                                                  queue:(dispatch_queue_t)queue
                                      completionHandler:
                                          (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRNullableTestClusterClusterSimpleEnumAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TestCluster::Attributes::NullableEnumAttr::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<NullableTestClusterClusterSimpleEnumAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeNullableStructWithCompletionHandler:(void (^)(MTRTestClusterClusterSimpleStruct * _Nullable value,
                                                             NSError * _Nullable error))completionHandler
{
    new MTRTestClusterNullableStructStructAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::NullableStruct::TypeInfo;
            auto successFn = Callback<TestClusterNullableStructStructAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeNullableStructWithValue:(MTRTestClusterClusterSimpleStruct * _Nullable)value
                            completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeNullableStructWithValue:(MTRTestClusterClusterSimpleStruct * _Nullable) value
                                         params:nil
                              completionHandler:completionHandler];
}
- (void)writeAttributeNullableStructWithValue:(MTRTestClusterClusterSimpleStruct * _Nullable)value
                                       params:(MTRWriteParams * _Nullable)params
                            completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::NullableStruct::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0.a = value.a.unsignedCharValue;
                nonNullValue_0.b = value.b.boolValue;
                nonNullValue_0.c = static_cast<std::remove_reference_t<decltype(nonNullValue_0.c)>>(value.c.unsignedCharValue);
                nonNullValue_0.d = [self asByteSpan:value.d];
                nonNullValue_0.e = [self asCharSpan:value.e];
                nonNullValue_0.f = static_cast<std::remove_reference_t<decltype(nonNullValue_0.f)>>(value.f.unsignedCharValue);
                nonNullValue_0.g = value.g.floatValue;
                nonNullValue_0.h = value.h.doubleValue;
            }
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeNullableStructWithMinInterval:(NSNumber * _Nonnull)minInterval
                                            maxInterval:(NSNumber * _Nonnull)maxInterval
                                                 params:(MTRSubscribeParams * _Nullable)params
                                subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                          reportHandler:(void (^)(MTRTestClusterClusterSimpleStruct * _Nullable value,
                                                            NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRTestClusterNullableStructStructAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::NullableStruct::TypeInfo;
            auto successFn = Callback<TestClusterNullableStructStructAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRTestClusterNullableStructStructAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeNullableStructWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                             endpoint:(NSNumber *)endpoint
                                                queue:(dispatch_queue_t)queue
                                    completionHandler:(void (^)(MTRTestClusterClusterSimpleStruct * _Nullable value,
                                                          NSError * _Nullable error))completionHandler
{
    new MTRTestClusterNullableStructStructAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TestCluster::Attributes::NullableStruct::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<TestClusterNullableStructStructAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeNullableRangeRestrictedInt8uWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::NullableRangeRestrictedInt8u::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeNullableRangeRestrictedInt8uWithValue:(NSNumber * _Nullable)value
                                          completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeNullableRangeRestrictedInt8uWithValue:(NSNumber * _Nullable) value
                                                       params:nil
                                            completionHandler:completionHandler];
}
- (void)writeAttributeNullableRangeRestrictedInt8uWithValue:(NSNumber * _Nullable)value
                                                     params:(MTRWriteParams * _Nullable)params
                                          completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::NullableRangeRestrictedInt8u::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.unsignedCharValue;
            }
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeNullableRangeRestrictedInt8uWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                                               params:(MTRSubscribeParams * _Nullable)params
                                              subscriptionEstablished:
                                                  (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                        reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                          NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt8uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::NullableRangeRestrictedInt8u::TypeInfo;
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt8uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeNullableRangeRestrictedInt8uWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                           endpoint:(NSNumber *)endpoint
                                                              queue:(dispatch_queue_t)queue
                                                  completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TestCluster::Attributes::NullableRangeRestrictedInt8u::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt8uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeNullableRangeRestrictedInt8sWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::NullableRangeRestrictedInt8s::TypeInfo;
            auto successFn = Callback<NullableInt8sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeNullableRangeRestrictedInt8sWithValue:(NSNumber * _Nullable)value
                                          completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeNullableRangeRestrictedInt8sWithValue:(NSNumber * _Nullable) value
                                                       params:nil
                                            completionHandler:completionHandler];
}
- (void)writeAttributeNullableRangeRestrictedInt8sWithValue:(NSNumber * _Nullable)value
                                                     params:(MTRWriteParams * _Nullable)params
                                          completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::NullableRangeRestrictedInt8s::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.charValue;
            }
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeNullableRangeRestrictedInt8sWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                          maxInterval:(NSNumber * _Nonnull)maxInterval
                                                               params:(MTRSubscribeParams * _Nullable)params
                                              subscriptionEstablished:
                                                  (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                        reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                          NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt8sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::NullableRangeRestrictedInt8s::TypeInfo;
            auto successFn = Callback<NullableInt8sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt8sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeNullableRangeRestrictedInt8sWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                           endpoint:(NSNumber *)endpoint
                                                              queue:(dispatch_queue_t)queue
                                                  completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                        NSError * _Nullable error))completionHandler
{
    new MTRNullableInt8sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TestCluster::Attributes::NullableRangeRestrictedInt8s::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt8sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeNullableRangeRestrictedInt16uWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                            NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::NullableRangeRestrictedInt16u::TypeInfo;
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeNullableRangeRestrictedInt16uWithValue:(NSNumber * _Nullable)value
                                           completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeNullableRangeRestrictedInt16uWithValue:(NSNumber * _Nullable) value
                                                        params:nil
                                             completionHandler:completionHandler];
}
- (void)writeAttributeNullableRangeRestrictedInt16uWithValue:(NSNumber * _Nullable)value
                                                      params:(MTRWriteParams * _Nullable)params
                                           completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::NullableRangeRestrictedInt16u::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.unsignedShortValue;
            }
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeNullableRangeRestrictedInt16uWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                params:(MTRSubscribeParams * _Nullable)params
                                               subscriptionEstablished:
                                                   (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                         reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::NullableRangeRestrictedInt16u::TypeInfo;
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeNullableRangeRestrictedInt16uWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                            endpoint:(NSNumber *)endpoint
                                                               queue:(dispatch_queue_t)queue
                                                   completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TestCluster::Attributes::NullableRangeRestrictedInt16u::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeNullableRangeRestrictedInt16sWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                                            NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16sAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::NullableRangeRestrictedInt16s::TypeInfo;
            auto successFn = Callback<NullableInt16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)writeAttributeNullableRangeRestrictedInt16sWithValue:(NSNumber * _Nullable)value
                                           completionHandler:(StatusCompletion)completionHandler
{
    [self writeAttributeNullableRangeRestrictedInt16sWithValue:(NSNumber * _Nullable) value
                                                        params:nil
                                             completionHandler:completionHandler];
}
- (void)writeAttributeNullableRangeRestrictedInt16sWithValue:(NSNumber * _Nullable)value
                                                      params:(MTRWriteParams * _Nullable)params
                                           completionHandler:(StatusCompletion)completionHandler
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    new MTRDefaultSuccessCallbackBridge(
        self.callbackQueue, self.device,
        ^(id _Nullable ignored, NSError * _Nullable error) {
            completionHandler(error);
        },
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            chip::Optional<uint16_t> timedWriteTimeout;
            if (params != nil) {
                if (params.timedWriteTimeout != nil) {
                    timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
                }
            }

            ListFreer listFreer;
            using TypeInfo = TestCluster::Attributes::NullableRangeRestrictedInt16s::TypeInfo;
            TypeInfo::Type cppValue;
            if (value == nil) {
                cppValue.SetNull();
            } else {
                auto & nonNullValue_0 = cppValue.SetNonNull();
                nonNullValue_0 = value.shortValue;
            }
            auto successFn = Callback<DefaultSuccessCallbackType>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.WriteAttribute<TypeInfo>(
                cppValue, successFn->mContext, successFn->mCall, failureFn->mCall, timedWriteTimeout);
        });
}

- (void)subscribeAttributeNullableRangeRestrictedInt16sWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                                params:(MTRSubscribeParams * _Nullable)params
                                               subscriptionEstablished:
                                                   (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                         reportHandler:(void (^)(NSNumber * _Nullable value,
                                                                           NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRNullableInt16sAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::NullableRangeRestrictedInt16s::TypeInfo;
            auto successFn = Callback<NullableInt16sAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRNullableInt16sAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeNullableRangeRestrictedInt16sWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                            endpoint:(NSNumber *)endpoint
                                                               queue:(dispatch_queue_t)queue
                                                   completionHandler:(void (^)(NSNumber * _Nullable value,
                                                                         NSError * _Nullable error))completionHandler
{
    new MTRNullableInt16sAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TestCluster::Attributes::NullableRangeRestrictedInt16s::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<NullableInt16sAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                   NSError * _Nullable error))completionHandler
{
    new MTRTestClusterGeneratedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<TestClusterGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                  maxInterval:(NSNumber * _Nonnull)maxInterval
                                                       params:(MTRSubscribeParams * _Nullable)params
                                      subscriptionEstablished:
                                          (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                                reportHandler:
                                                    (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRTestClusterGeneratedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::GeneratedCommandList::TypeInfo;
            auto successFn = Callback<TestClusterGeneratedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRTestClusterGeneratedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeGeneratedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                   endpoint:(NSNumber *)endpoint
                                                      queue:(dispatch_queue_t)queue
                                          completionHandler:
                                              (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRTestClusterGeneratedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TestCluster::Attributes::GeneratedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<TestClusterGeneratedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAcceptedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value,
                                                                  NSError * _Nullable error))completionHandler
{
    new MTRTestClusterAcceptedCommandListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<TestClusterAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAcceptedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                                 maxInterval:(NSNumber * _Nonnull)maxInterval
                                                      params:(MTRSubscribeParams * _Nullable)params
                                     subscriptionEstablished:
                                         (SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                               reportHandler:
                                                   (void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRTestClusterAcceptedCommandListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::AcceptedCommandList::TypeInfo;
            auto successFn = Callback<TestClusterAcceptedCommandListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRTestClusterAcceptedCommandListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAcceptedCommandListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                                  endpoint:(NSNumber *)endpoint
                                                     queue:(dispatch_queue_t)queue
                                         completionHandler:
                                             (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRTestClusterAcceptedCommandListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TestCluster::Attributes::AcceptedCommandList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<TestClusterAcceptedCommandListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeAttributeListWithCompletionHandler:(void (^)(
                                                            NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRTestClusterAttributeListListAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<TestClusterAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeAttributeListWithMinInterval:(NSNumber * _Nonnull)minInterval
                                           maxInterval:(NSNumber * _Nonnull)maxInterval
                                                params:(MTRSubscribeParams * _Nullable)params
                               subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                         reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRTestClusterAttributeListListAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::AttributeList::TypeInfo;
            auto successFn = Callback<TestClusterAttributeListListAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRTestClusterAttributeListListAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeAttributeListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                            endpoint:(NSNumber *)endpoint
                                               queue:(dispatch_queue_t)queue
                                   completionHandler:
                                       (void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRTestClusterAttributeListListAttributeCallbackBridge(
        queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
            if (attributeCacheContainer.cppAttributeCache) {
                chip::app::ConcreteAttributePath path;
                using TypeInfo = TestCluster::Attributes::AttributeList::TypeInfo;
                path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
                path.mClusterId = TypeInfo::GetClusterId();
                path.mAttributeId = TypeInfo::GetAttributeId();
                TypeInfo::DecodableType value;
                CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
                auto successFn = Callback<TestClusterAttributeListListAttributeCallback>::FromCancelable(success);
                if (err == CHIP_NO_ERROR) {
                    successFn->mCall(successFn->mContext, value);
                }
                return err;
            }
            return CHIP_ERROR_NOT_FOUND;
        });
}

- (void)readAttributeFeatureMapWithCompletionHandler:(void (^)(
                                                         NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeFeatureMapWithMinInterval:(NSNumber * _Nonnull)minInterval
                                        maxInterval:(NSNumber * _Nonnull)maxInterval
                                             params:(MTRSubscribeParams * _Nullable)params
                            subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                      reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt32uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::FeatureMap::TypeInfo;
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt32uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeFeatureMapWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                         endpoint:(NSNumber *)endpoint
                                            queue:(dispatch_queue_t)queue
                                completionHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt32uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TestCluster::Attributes::FeatureMap::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int32uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

- (void)readAttributeClusterRevisionWithCompletionHandler:(void (^)(NSNumber * _Nullable value,
                                                              NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(self.callbackQueue, self.device, completionHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            using TypeInfo = TestCluster::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);
            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.ReadAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall);
        });
}

- (void)subscribeAttributeClusterRevisionWithMinInterval:(NSNumber * _Nonnull)minInterval
                                             maxInterval:(NSNumber * _Nonnull)maxInterval
                                                  params:(MTRSubscribeParams * _Nullable)params
                                 subscriptionEstablished:(SubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler
                                           reportHandler:
                                               (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler
{
    // Make a copy of params before we go async.
    minInterval = [minInterval copy];
    maxInterval = [maxInterval copy];
    params = [params copy];
    new MTRInt16uAttributeCallbackSubscriptionBridge(
        self.callbackQueue, self.device, reportHandler,
        ^(ExchangeManager & exchangeManager, const SessionHandle & session, Cancelable * success, Cancelable * failure) {
            if (params != nil && params.autoResubscribe != nil && ![params.autoResubscribe boolValue]) {
                // We don't support disabling auto-resubscribe.
                return CHIP_ERROR_INVALID_ARGUMENT;
            }
            using TypeInfo = TestCluster::Attributes::ClusterRevision::TypeInfo;
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            auto failureFn = Callback<DefaultFailureCallbackType>::FromCancelable(failure);

            chip::Controller::TestClusterCluster cppCluster(exchangeManager, session, self->_endpoint);
            return cppCluster.SubscribeAttribute<TypeInfo>(successFn->mContext, successFn->mCall, failureFn->mCall,
                [minInterval unsignedShortValue], [maxInterval unsignedShortValue],
                MTRInt16uAttributeCallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
                params == nil || params.fabricFiltered == nil || [params.fabricFiltered boolValue],
                params != nil && params.keepPreviousSubscriptions != nil && [params.keepPreviousSubscriptions boolValue]);
        },
        subscriptionEstablishedHandler);
}

+ (void)readAttributeClusterRevisionWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer
                                              endpoint:(NSNumber *)endpoint
                                                 queue:(dispatch_queue_t)queue
                                     completionHandler:
                                         (void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completionHandler
{
    new MTRInt16uAttributeCallbackBridge(queue, completionHandler, ^(Cancelable * success, Cancelable * failure) {
        if (attributeCacheContainer.cppAttributeCache) {
            chip::app::ConcreteAttributePath path;
            using TypeInfo = TestCluster::Attributes::ClusterRevision::TypeInfo;
            path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
            path.mClusterId = TypeInfo::GetClusterId();
            path.mAttributeId = TypeInfo::GetAttributeId();
            TypeInfo::DecodableType value;
            CHIP_ERROR err = attributeCacheContainer.cppAttributeCache->Get<TypeInfo>(path, value);
            auto successFn = Callback<Int16uAttributeCallback>::FromCancelable(success);
            if (err == CHIP_NO_ERROR) {
                successFn->mCall(successFn->mContext, value);
            }
            return err;
        }
        return CHIP_ERROR_NOT_FOUND;
    });
}

@end

// NOLINTEND(clang-analyzer-cplusplus.NewDeleteLeaks)
