From 80b7493f5e45f542096be70b6c284aec0a292552 Mon Sep 17 00:00:00 2001 From: pankore <86098180+pankore@users.noreply.github.com> Date: Wed, 5 Oct 2022 04:07:30 +0800 Subject: [PATCH 01/13] [Chef] Implement Z2 flashing through flash.sh script (#23011) --- examples/chef/chef.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/examples/chef/chef.py b/examples/chef/chef.py index 411151a8def953..7d296d937e911c 100755 --- a/examples/chef/chef.py +++ b/examples/chef/chef.py @@ -696,6 +696,7 @@ def main() -> int: elif config['ameba']['MODEL'] == 'Z2': shell.run_cmd( f"cd {config['ameba']['AMEBA_SDK']}/project/realtek_amebaz2_v0_example/GCC-RELEASE") + shell.run_cmd("rm -f project_include.mk") with open(f"{config['ameba']['AMEBA_SDK']}/project/realtek_amebaz2_v0_example/GCC-RELEASE/project_include.mk", "w") as f: f.write(textwrap.dedent(f"""\ SAMPLE_NAME = {options.sample_device_type_name} @@ -819,8 +820,11 @@ def main() -> int: shell.run_cmd( f"{config['ameba']['AMEBA_SDK']}/tools/AmebaD/Image_Tool_Linux/flash.sh {config['ameba']['TTY']} {config['ameba']['AMEBA_SDK']}/project/realtek_amebaD_va0_example/GCC-RELEASE/out", raise_on_returncode=False) else: - flush_print( - "Ameba Z2 currently does not support flashing image through script, stil WIP") + shell.run_cmd(f"cd {_CHEF_SCRIPT_PATH}/ameba") + shell.run_cmd( + f"cd {config['ameba']['AMEBA_SDK']}/tools/AmebaZ2/Image_Tool_Linux") + shell.run_cmd( + f"{config['ameba']['AMEBA_SDK']}/tools/AmebaZ2/Image_Tool_Linux/flash.sh {config['ameba']['TTY']} {config['ameba']['AMEBA_SDK']}/project/realtek_amebaz2_v0_example/GCC-RELEASE/application_is/Debug/bin", raise_on_returncode=False) # # Terminal interaction From 5b1af33dc4167f84250d3707c0a122724e80e84c Mon Sep 17 00:00:00 2001 From: pankore <86098180+pankore@users.noreply.github.com> Date: Wed, 5 Oct 2022 04:07:44 +0800 Subject: [PATCH 02/13] [Ameba] Replace BLE C2 notify with indicate as required by Matter Spec (#23013) * Update Dockerfile * Update version --- integrations/docker/images/chip-build-ameba/Dockerfile | 2 +- integrations/docker/images/chip-build/version | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/integrations/docker/images/chip-build-ameba/Dockerfile b/integrations/docker/images/chip-build-ameba/Dockerfile index c8307ae64986f8..3d3b055e820887 100644 --- a/integrations/docker/images/chip-build-ameba/Dockerfile +++ b/integrations/docker/images/chip-build-ameba/Dockerfile @@ -3,7 +3,7 @@ FROM connectedhomeip/chip-build:${VERSION} # Setup Ameba ARG AMEBA_DIR=/opt/ameba -ARG TAG_NAME=ameba_update_2022_07_25 +ARG TAG_NAME=ameba_update_2022_10_03 RUN set -x \ && apt-get update \ && mkdir ${AMEBA_DIR} \ diff --git a/integrations/docker/images/chip-build/version b/integrations/docker/images/chip-build/version index 1683f3fe2579b9..b288fd5e8ac786 100644 --- a/integrations/docker/images/chip-build/version +++ b/integrations/docker/images/chip-build/version @@ -1 +1 @@ -0.6.02 Version bump reason: Update NXP SDK PATH +0.6.03 Version bump reason: [Ameba] Replace C2 notify with indicate as required by Matter spec From fa9f9772a32804c1e8ed945c6e47fbb1b4d3cc86 Mon Sep 17 00:00:00 2001 From: Peter Qiu <114182543+zqiu-nest@users.noreply.github.com> Date: Tue, 4 Oct 2022 16:08:10 -0400 Subject: [PATCH 03/13] [Linux]Add build arg to allow external logging implementation (#22829) * Linux: add build arg to allow external logging implementation The will allow target platform/application to provide its own logging implementation, such as writing logs to file, instead of logging to stdout. * Update core.gni --- src/lib/core/core.gni | 5 +++++ src/platform/Linux/BUILD.gn | 5 ++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/lib/core/core.gni b/src/lib/core/core.gni index c49357dffcab68..da4cf547e7c80a 100644 --- a/src/lib/core/core.gni +++ b/src/lib/core/core.gni @@ -47,6 +47,11 @@ declare_args() { # Configure chip logging to output through pigweed logging. chip_use_pw_logging = false + # Configure chip logging to output through external logging implementation. + # External code will need to provide implementation for CHIP log output + # function (LogV), which is defined in "src/platform/logging/LogV.h". + chip_use_external_logging = false + # Enable short error strings. chip_config_short_error_str = false diff --git a/src/platform/Linux/BUILD.gn b/src/platform/Linux/BUILD.gn index 5a66ab0ccc335d..2088bfb83daf00 100644 --- a/src/platform/Linux/BUILD.gn +++ b/src/platform/Linux/BUILD.gn @@ -67,7 +67,6 @@ static_library("Linux") { "InetPlatformConfig.h", "KeyValueStoreManagerImpl.cpp", "KeyValueStoreManagerImpl.h", - "Logging.cpp", "NetworkCommissioningDriver.h", "NetworkCommissioningEthernetDriver.cpp", "PlatformManagerImpl.cpp", @@ -78,6 +77,10 @@ static_library("Linux") { "SystemTimeSupport.cpp", ] + if (!chip_use_external_logging) { + sources += [ "Logging.cpp" ] + } + if (chip_enable_openthread) { sources += [ "NetworkCommissioningThreadDriver.cpp" ] } From bd83c1a6d55559962903b774b58bc382107ae0bb Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Tue, 4 Oct 2022 16:22:19 -0400 Subject: [PATCH 04/13] Add an API to stop a DNS-SD browse operation. (#22823) * Add an API to stop a DNS-SD browse operation. Most backends don't implement this yet. Darwin does, and no longer stops Browse operations itself. Fixes https://github.com/project-chip/connectedhomeip/issues/19194 May provide a way toward fixing https://github.com/project-chip/connectedhomeip/issues/13275 * Address review comments. * Address more review comments. --- .../commands/pairing/PairingCommand.cpp | 3 +- .../commands/discovery/DiscoveryCommands.cpp | 1 + src/controller/CHIPDeviceController.cpp | 5 ++ src/controller/CHIPDeviceController.h | 6 +++ src/controller/SetUpCodePairer.cpp | 2 + .../TestCommissionableNodeController.cpp | 1 + src/lib/dnssd/ActiveResolveAttempts.cpp | 13 +++++ src/lib/dnssd/ActiveResolveAttempts.h | 4 ++ src/lib/dnssd/Discovery_ImplPlatform.cpp | 53 +++++++++++++++++-- src/lib/dnssd/Discovery_ImplPlatform.h | 1 + src/lib/dnssd/Resolver.h | 8 +++ src/lib/dnssd/ResolverProxy.h | 5 ++ src/lib/dnssd/Resolver_ImplMinimalMdns.cpp | 11 ++++ src/lib/dnssd/Resolver_ImplNone.cpp | 6 +++ src/lib/dnssd/platform/Dnssd.h | 19 ++++++- src/platform/Ameba/DnssdImpl.cpp | 8 ++- src/platform/Darwin/DnssdContexts.cpp | 6 +++ src/platform/Darwin/DnssdImpl.cpp | 36 +++++++++++-- src/platform/Darwin/DnssdImpl.h | 3 ++ src/platform/ESP32/DnssdImpl.cpp | 12 ++++- src/platform/Linux/DnssdImpl.cpp | 9 +++- src/platform/OpenThread/DnssdImpl.cpp | 8 ++- src/platform/Tizen/DnssdImpl.cpp | 10 +++- src/platform/android/DnssdImpl.cpp | 8 ++- src/platform/bouffalolab/BL602/DnssdImpl.cpp | 8 ++- src/platform/fake/DnssdImpl.cpp | 8 ++- src/platform/mt793x/DnssdImpl.cpp | 12 ++++- src/platform/tests/TestDnssd.cpp | 3 +- src/platform/webos/DnssdImpl.cpp | 9 +++- 29 files changed, 256 insertions(+), 22 deletions(-) mode change 100755 => 100644 src/platform/Ameba/DnssdImpl.cpp diff --git a/examples/chip-tool/commands/pairing/PairingCommand.cpp b/examples/chip-tool/commands/pairing/PairingCommand.cpp index 1905361570f6f8..b2aec812597a88 100644 --- a/examples/chip-tool/commands/pairing/PairingCommand.cpp +++ b/examples/chip-tool/commands/pairing/PairingCommand.cpp @@ -237,7 +237,8 @@ void PairingCommand::OnDiscoveredDevice(const chip::Dnssd::DiscoveredNodeData & nodeData.resolutionData.ipAddress[0].ToString(buf); ChipLogProgress(chipTool, "Discovered Device: %s:%u", buf, port); - // Stop Mdns discovery. Is it the right method ? + // Stop Mdns discovery. + CurrentCommissioner().StopCommissionableDiscovery(); CurrentCommissioner().RegisterDeviceDiscoveryDelegate(nullptr); Inet::InterfaceId interfaceId = diff --git a/src/app/tests/suites/commands/discovery/DiscoveryCommands.cpp b/src/app/tests/suites/commands/discovery/DiscoveryCommands.cpp index d1ae4d1fc25be8..7cf0dde53f525e 100644 --- a/src/app/tests/suites/commands/discovery/DiscoveryCommands.cpp +++ b/src/app/tests/suites/commands/discovery/DiscoveryCommands.cpp @@ -125,6 +125,7 @@ CHIP_ERROR DiscoveryCommands::SetupDiscoveryCommands() CHIP_ERROR DiscoveryCommands::TearDownDiscoveryCommands() { + mDNSResolver.StopDiscovery(); mDNSResolver.SetOperationalDelegate(nullptr); mDNSResolver.SetCommissioningDelegate(nullptr); return CHIP_NO_ERROR; diff --git a/src/controller/CHIPDeviceController.cpp b/src/controller/CHIPDeviceController.cpp index 7ac27332ee0f38..6b71c9fbbd9fcd 100644 --- a/src/controller/CHIPDeviceController.cpp +++ b/src/controller/CHIPDeviceController.cpp @@ -1431,6 +1431,11 @@ CHIP_ERROR DeviceCommissioner::DiscoverCommissionableNodes(Dnssd::DiscoveryFilte return mDNSResolver.DiscoverCommissionableNodes(filter); } +CHIP_ERROR DeviceCommissioner::StopCommissionableDiscovery() +{ + return mDNSResolver.StopDiscovery(); +} + const Dnssd::DiscoveredNodeData * DeviceCommissioner::GetDiscoveredDevice(int idx) { return GetDiscoveredNode(idx); diff --git a/src/controller/CHIPDeviceController.h b/src/controller/CHIPDeviceController.h index 3b40612e6f4ae2..aa5e2936216604 100644 --- a/src/controller/CHIPDeviceController.h +++ b/src/controller/CHIPDeviceController.h @@ -597,6 +597,12 @@ class DLL_EXPORT DeviceCommissioner : public DeviceController, */ CHIP_ERROR DiscoverCommissionableNodes(Dnssd::DiscoveryFilter filter); + /** + * Stop commissionable discovery triggered by a previous + * DiscoverCommissionableNodes call. + */ + CHIP_ERROR StopCommissionableDiscovery(); + /** * @brief * Returns information about discovered devices. diff --git a/src/controller/SetUpCodePairer.cpp b/src/controller/SetUpCodePairer.cpp index ddd0f8fe6d01f6..3a7f218ea4821b 100644 --- a/src/controller/SetUpCodePairer.cpp +++ b/src/controller/SetUpCodePairer.cpp @@ -187,6 +187,8 @@ CHIP_ERROR SetUpCodePairer::StopConnectOverIP() mWaitingForDiscovery[kIPTransport] = false; currentFilter.type = Dnssd::DiscoveryFilterType::kNone; + + mCommissioner->StopCommissionableDiscovery(); return CHIP_NO_ERROR; } diff --git a/src/controller/tests/TestCommissionableNodeController.cpp b/src/controller/tests/TestCommissionableNodeController.cpp index 258be7225469c4..41d5663bafb0b6 100644 --- a/src/controller/tests/TestCommissionableNodeController.cpp +++ b/src/controller/tests/TestCommissionableNodeController.cpp @@ -42,6 +42,7 @@ class MockResolver : public Resolver { return CHIP_ERROR_NOT_IMPLEMENTED; } + CHIP_ERROR StopDiscovery() override { return CHIP_ERROR_NOT_IMPLEMENTED; } CHIP_ERROR InitStatus = CHIP_NO_ERROR; CHIP_ERROR ResolveNodeIdStatus = CHIP_NO_ERROR; diff --git a/src/lib/dnssd/ActiveResolveAttempts.cpp b/src/lib/dnssd/ActiveResolveAttempts.cpp index aa08abdb7deff2..9e458207aeb3f7 100644 --- a/src/lib/dnssd/ActiveResolveAttempts.cpp +++ b/src/lib/dnssd/ActiveResolveAttempts.cpp @@ -79,6 +79,19 @@ void ActiveResolveAttempts::CompleteIpResolution(SerializedQNameIterator targetH } } +CHIP_ERROR ActiveResolveAttempts::CompleteAllBrowses() +{ + for (auto & item : mRetryQueue) + { + if (item.attempt.IsBrowse()) + { + item.attempt.Clear(); + } + } + + return CHIP_NO_ERROR; +} + void ActiveResolveAttempts::MarkPending(const chip::PeerId & peerId) { MarkPending(ScheduledAttempt(peerId, /* firstSend */ true)); diff --git a/src/lib/dnssd/ActiveResolveAttempts.h b/src/lib/dnssd/ActiveResolveAttempts.h index 7ce121319ce3f2..6ba51cb151e7b5 100644 --- a/src/lib/dnssd/ActiveResolveAttempts.h +++ b/src/lib/dnssd/ActiveResolveAttempts.h @@ -204,6 +204,10 @@ class ActiveResolveAttempts void Complete(const chip::Dnssd::DiscoveredNodeData & data); void CompleteIpResolution(SerializedQNameIterator targetHostName); + /// Mark all browse-type scheduled attemptes as a success, removing them + /// from the internal list. + CHIP_ERROR CompleteAllBrowses(); + /// Mark that a resolution is pending, adding it to the internal list /// /// Once this complete, this peer id will be returned immediately diff --git a/src/lib/dnssd/Discovery_ImplPlatform.cpp b/src/lib/dnssd/Discovery_ImplPlatform.cpp index a7347122f6f20f..6a6bc64aea3e77 100644 --- a/src/lib/dnssd/Discovery_ImplPlatform.cpp +++ b/src/lib/dnssd/Discovery_ImplPlatform.cpp @@ -153,6 +153,14 @@ static void HandleNodeBrowse(void * context, DnssdService * services, size_t ser if (error != CHIP_NO_ERROR) { + // We don't have access to the ResolverProxy here to clear out its + // mDiscoveryContext. The underlying implementation of + // ChipDnssdStopBrowse needs to handle a possibly-stale reference + // safely, so this won't lead to crashes, but it can lead to + // mis-behavior if a stale mDiscoveryContext happens to match a newer + // browse operation. + // + // TODO: Have a way to clear that state here. proxy->Release(); return; } @@ -174,6 +182,14 @@ static void HandleNodeBrowse(void * context, DnssdService * services, size_t ser if (finalBrowse) { + // We don't have access to the ResolverProxy here to clear out its + // mDiscoveryContext. The underlying implementation of + // ChipDnssdStopBrowse needs to handle a possibly-stale reference + // safely, so this won't lead to crashes, but it can lead to + // mis-behavior if a stale mDiscoveryContext happens to match a newer + // browse operation. + // + // TODO: Have a way to clear that state here. proxy->Release(); } } @@ -616,6 +632,12 @@ CHIP_ERROR DiscoveryImplPlatform::DiscoverCommissioners(DiscoveryFilter filter) return mResolverProxy.DiscoverCommissioners(filter); } +CHIP_ERROR DiscoveryImplPlatform::StopDiscovery() +{ + ReturnErrorOnFailure(InitImpl()); + return mResolverProxy.StopDiscovery(); +} + DiscoveryImplPlatform & DiscoveryImplPlatform::GetInstance() { return sManager; @@ -656,6 +678,8 @@ ResolverProxy::~ResolverProxy() CHIP_ERROR ResolverProxy::DiscoverCommissionableNodes(DiscoveryFilter filter) { + StopDiscovery(); + VerifyOrReturnError(mDelegate != nullptr, CHIP_ERROR_INCORRECT_STATE); mDelegate->Retain(); @@ -674,12 +698,17 @@ CHIP_ERROR ResolverProxy::DiscoverCommissionableNodes(DiscoveryFilter filter) char serviceName[kMaxCommissionableServiceNameSize]; ReturnErrorOnFailure(MakeServiceTypeName(serviceName, sizeof(serviceName), filter, DiscoveryType::kCommissionableNode)); - return ChipDnssdBrowse(serviceName, DnssdServiceProtocol::kDnssdProtocolUdp, Inet::IPAddressType::kAny, - Inet::InterfaceId::Null(), HandleNodeBrowse, mDelegate); + intptr_t browseIdentifier; + ReturnErrorOnFailure(ChipDnssdBrowse(serviceName, DnssdServiceProtocol::kDnssdProtocolUdp, Inet::IPAddressType::kAny, + Inet::InterfaceId::Null(), HandleNodeBrowse, mDelegate, &browseIdentifier)); + mDiscoveryContext.Emplace(browseIdentifier); + return CHIP_NO_ERROR; } CHIP_ERROR ResolverProxy::DiscoverCommissioners(DiscoveryFilter filter) { + StopDiscovery(); + VerifyOrReturnError(mDelegate != nullptr, CHIP_ERROR_INCORRECT_STATE); mDelegate->Retain(); @@ -698,8 +727,24 @@ CHIP_ERROR ResolverProxy::DiscoverCommissioners(DiscoveryFilter filter) char serviceName[kMaxCommissionerServiceNameSize]; ReturnErrorOnFailure(MakeServiceTypeName(serviceName, sizeof(serviceName), filter, DiscoveryType::kCommissionerNode)); - return ChipDnssdBrowse(serviceName, DnssdServiceProtocol::kDnssdProtocolUdp, Inet::IPAddressType::kAny, - Inet::InterfaceId::Null(), HandleNodeBrowse, mDelegate); + intptr_t browseIdentifier; + ReturnErrorOnFailure(ChipDnssdBrowse(serviceName, DnssdServiceProtocol::kDnssdProtocolUdp, Inet::IPAddressType::kAny, + Inet::InterfaceId::Null(), HandleNodeBrowse, mDelegate, &browseIdentifier)); + mDiscoveryContext.Emplace(browseIdentifier); + return CHIP_NO_ERROR; +} + +CHIP_ERROR ResolverProxy::StopDiscovery() +{ + if (!mDiscoveryContext.HasValue()) + { + // No discovery going on. + return CHIP_NO_ERROR; + } + + CHIP_ERROR err = ChipDnssdStopBrowse(mDiscoveryContext.Value()); + mDiscoveryContext.ClearValue(); + return err; } } // namespace Dnssd diff --git a/src/lib/dnssd/Discovery_ImplPlatform.h b/src/lib/dnssd/Discovery_ImplPlatform.h index 1bf677d44ee501..dcee5bc0974f7c 100644 --- a/src/lib/dnssd/Discovery_ImplPlatform.h +++ b/src/lib/dnssd/Discovery_ImplPlatform.h @@ -57,6 +57,7 @@ class DiscoveryImplPlatform : public ServiceAdvertiser, public Resolver CHIP_ERROR ResolveNodeId(const PeerId & peerId, Inet::IPAddressType type) override; CHIP_ERROR DiscoverCommissionableNodes(DiscoveryFilter filter = DiscoveryFilter()) override; CHIP_ERROR DiscoverCommissioners(DiscoveryFilter filter = DiscoveryFilter()) override; + CHIP_ERROR StopDiscovery() override; static DiscoveryImplPlatform & GetInstance(); diff --git a/src/lib/dnssd/Resolver.h b/src/lib/dnssd/Resolver.h index 140a71617645b5..dddbed07625ebe 100644 --- a/src/lib/dnssd/Resolver.h +++ b/src/lib/dnssd/Resolver.h @@ -390,6 +390,14 @@ class Resolver */ virtual CHIP_ERROR DiscoverCommissioners(DiscoveryFilter filter = DiscoveryFilter()) = 0; + /** + * Stop discovery (of commissionable or commissioner nodes). + * + * Some back ends may not support stopping discovery, so consumers should + * not assume they will stop getting callbacks after calling this. + */ + virtual CHIP_ERROR StopDiscovery() = 0; + /** * Provides the system-wide implementation of the service resolver */ diff --git a/src/lib/dnssd/ResolverProxy.h b/src/lib/dnssd/ResolverProxy.h index 38ac51c07eb537..36ada23a486dcf 100644 --- a/src/lib/dnssd/ResolverProxy.h +++ b/src/lib/dnssd/ResolverProxy.h @@ -152,11 +152,16 @@ class ResolverProxy : public Resolver CHIP_ERROR ResolveNodeId(const PeerId & peerId, Inet::IPAddressType type) override; CHIP_ERROR DiscoverCommissionableNodes(DiscoveryFilter filter = DiscoveryFilter()) override; CHIP_ERROR DiscoverCommissioners(DiscoveryFilter filter = DiscoveryFilter()) override; + CHIP_ERROR StopDiscovery() override; private: ResolverDelegateProxy * mDelegate = nullptr; OperationalResolveDelegate * mPreInitOperationalDelegate = nullptr; CommissioningResolveDelegate * mPreInitCommissioningDelegate = nullptr; + + // While discovery (commissionable or commissioner) is ongoing, + // mDiscoveryContext may have a value to allow StopDiscovery to work. + Optional mDiscoveryContext; }; } // namespace Dnssd diff --git a/src/lib/dnssd/Resolver_ImplMinimalMdns.cpp b/src/lib/dnssd/Resolver_ImplMinimalMdns.cpp index 76aef704be593f..cf168d78139c9d 100644 --- a/src/lib/dnssd/Resolver_ImplMinimalMdns.cpp +++ b/src/lib/dnssd/Resolver_ImplMinimalMdns.cpp @@ -281,6 +281,7 @@ class MinMdnsResolver : public Resolver, public MdnsPacketDelegate CHIP_ERROR ResolveNodeId(const PeerId & peerId, Inet::IPAddressType type) override; CHIP_ERROR DiscoverCommissionableNodes(DiscoveryFilter filter = DiscoveryFilter()) override; CHIP_ERROR DiscoverCommissioners(DiscoveryFilter filter = DiscoveryFilter()) override; + CHIP_ERROR StopDiscovery() override; private: OperationalResolveDelegate * mOperationalDelegate = nullptr; @@ -633,6 +634,11 @@ CHIP_ERROR MinMdnsResolver::DiscoverCommissioners(DiscoveryFilter filter) return BrowseNodes(DiscoveryType::kCommissionerNode, filter); } +CHIP_ERROR MinMdnsResolver::StopDiscovery() +{ + return mActiveResolves.CompleteAllBrowses(); +} + CHIP_ERROR MinMdnsResolver::BrowseNodes(DiscoveryType type, DiscoveryFilter filter) { mActiveResolves.MarkPending(filter, type); @@ -712,5 +718,10 @@ CHIP_ERROR ResolverProxy::DiscoverCommissioners(DiscoveryFilter filter) return chip::Dnssd::Resolver::Instance().DiscoverCommissioners(filter); } +CHIP_ERROR ResolverProxy::StopDiscovery() +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + } // namespace Dnssd } // namespace chip diff --git a/src/lib/dnssd/Resolver_ImplNone.cpp b/src/lib/dnssd/Resolver_ImplNone.cpp index fad00bc1fdfada..5fe429f8a62444 100644 --- a/src/lib/dnssd/Resolver_ImplNone.cpp +++ b/src/lib/dnssd/Resolver_ImplNone.cpp @@ -42,6 +42,7 @@ class NoneResolver : public Resolver return CHIP_ERROR_NOT_IMPLEMENTED; } CHIP_ERROR DiscoverCommissioners(DiscoveryFilter filter = DiscoveryFilter()) override { return CHIP_ERROR_NOT_IMPLEMENTED; } + CHIP_ERROR StopDiscovery() override { return CHIP_ERROR_NOT_IMPLEMENTED; } }; NoneResolver gResolver; @@ -73,5 +74,10 @@ CHIP_ERROR ResolverProxy::DiscoverCommissioners(DiscoveryFilter filter) return CHIP_ERROR_NOT_IMPLEMENTED; } +CHIP_ERROR ResolverProxy::StopDiscovery() +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + } // namespace Dnssd } // namespace chip diff --git a/src/lib/dnssd/platform/Dnssd.h b/src/lib/dnssd/platform/Dnssd.h index 4ccd4d7e03aef6..1bce362b400782 100644 --- a/src/lib/dnssd/platform/Dnssd.h +++ b/src/lib/dnssd/platform/Dnssd.h @@ -203,6 +203,11 @@ CHIP_ERROR ChipDnssdFinalizeServiceUpdate(); * @param[in] interface The interface to send queries. * @param[in] callback The callback for found services. * @param[in] context The user context. + * @param[out] browseIdentifier an identifier for this browse operation. This + * can be used to call ChipDnssdStopBrowse. Only + * set on success. This value remains valid until + * the browse callback is called with an error or + * is called with finalBrowse set to true. * * @retval CHIP_NO_ERROR The browse succeeds. * @retval CHIP_ERROR_INVALID_ARGUMENT The type or callback is nullptr. @@ -210,7 +215,19 @@ CHIP_ERROR ChipDnssdFinalizeServiceUpdate(); * */ CHIP_ERROR ChipDnssdBrowse(const char * type, DnssdServiceProtocol protocol, chip::Inet::IPAddressType addressType, - chip::Inet::InterfaceId interface, DnssdBrowseCallback callback, void * context); + chip::Inet::InterfaceId interface, DnssdBrowseCallback callback, void * context, + intptr_t * browseIdentifier); + +/** + * Stop an ongoing browse, if supported by this backend. If successful, this + * will trigger a final callback, with either an error status or finalBrowse set + * to true, to the DnssdBrowseCallback that was passed to the ChipDnssdBrowse + * call that handed back this browseIdentifier. + * + * @param browseIdentifier an identifier for a browse operation that came from + * ChipDnssdBrowse. + */ +CHIP_ERROR ChipDnssdStopBrowse(intptr_t browseIdentifier); /** * This function resolves the services published by mDNS diff --git a/src/platform/Ameba/DnssdImpl.cpp b/src/platform/Ameba/DnssdImpl.cpp old mode 100755 new mode 100644 index 9d885676abd488..d12f006e5834b6 --- a/src/platform/Ameba/DnssdImpl.cpp +++ b/src/platform/Ameba/DnssdImpl.cpp @@ -97,7 +97,13 @@ CHIP_ERROR ChipDnssdStopPublish() } CHIP_ERROR ChipDnssdBrowse(const char * type, DnssdServiceProtocol protocol, chip::Inet::IPAddressType addressType, - chip::Inet::InterfaceId interface, DnssdBrowseCallback callback, void * context); + chip::Inet::InterfaceId interface, DnssdBrowseCallback callback, void * context, + intptr_t * browseIdentifier); +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +CHIP_ERROR ChipDnssdStopBrowse(intptr_t browseIdentifier) { return CHIP_ERROR_NOT_IMPLEMENTED; } diff --git a/src/platform/Darwin/DnssdContexts.cpp b/src/platform/Darwin/DnssdContexts.cpp index 4128bfa24e431c..2f2ae01e5e6bd8 100644 --- a/src/platform/Darwin/DnssdContexts.cpp +++ b/src/platform/Darwin/DnssdContexts.cpp @@ -299,6 +299,12 @@ void BrowseContext::DispatchSuccess() MdnsContexts::GetInstance().Remove(this); } +void BrowseContext::DispatchPartialSuccess() +{ + callback(context, services.data(), services.size(), false, CHIP_NO_ERROR); + services.clear(); +} + ResolveContext::ResolveContext(void * cbContext, DnssdResolveCallback cb, chip::Inet::IPAddressType cbAddressType) { type = ContextType::Resolve; diff --git a/src/platform/Darwin/DnssdImpl.cpp b/src/platform/Darwin/DnssdImpl.cpp index c8c94ca174baa7..a955941a8c633c 100644 --- a/src/platform/Darwin/DnssdImpl.cpp +++ b/src/platform/Darwin/DnssdImpl.cpp @@ -256,12 +256,12 @@ static void OnBrowse(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interf if (!(flags & kDNSServiceFlagsMoreComing)) { - sdCtx->Finalize(); + sdCtx->DispatchPartialSuccess(); } } CHIP_ERROR Browse(void * context, DnssdBrowseCallback callback, uint32_t interfaceId, const char * type, - DnssdServiceProtocol protocol) + DnssdServiceProtocol protocol, intptr_t * browseIdentifier) { auto sdCtx = chip::Platform::New(context, callback, protocol); VerifyOrReturnError(nullptr != sdCtx, CHIP_ERROR_NO_MEMORY); @@ -271,7 +271,9 @@ CHIP_ERROR Browse(void * context, DnssdBrowseCallback callback, uint32_t interfa auto err = DNSServiceBrowse(&sdRef, kBrowseFlags, interfaceId, type, kLocalDot, OnBrowse, sdCtx); VerifyOrReturnError(kDNSServiceErr_NoError == err, sdCtx->Finalize(err)); - return MdnsContexts::GetInstance().Add(sdCtx, sdRef); + ReturnErrorOnFailure(MdnsContexts::GetInstance().Add(sdCtx, sdRef)); + *browseIdentifier = reinterpret_cast(sdCtx); + return CHIP_NO_ERROR; } static void OnGetAddrInfo(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceId, DNSServiceErrorType err, @@ -398,7 +400,8 @@ CHIP_ERROR ChipDnssdFinalizeServiceUpdate() } CHIP_ERROR ChipDnssdBrowse(const char * type, DnssdServiceProtocol protocol, chip::Inet::IPAddressType addressType, - chip::Inet::InterfaceId interface, DnssdBrowseCallback callback, void * context) + chip::Inet::InterfaceId interface, DnssdBrowseCallback callback, void * context, + intptr_t * browseIdentifier) { VerifyOrReturnError(type != nullptr, CHIP_ERROR_INVALID_ARGUMENT); VerifyOrReturnError(callback != nullptr, CHIP_ERROR_INVALID_ARGUMENT); @@ -406,7 +409,30 @@ CHIP_ERROR ChipDnssdBrowse(const char * type, DnssdServiceProtocol protocol, chi auto regtype = GetFullTypeWithSubTypes(type, protocol); auto interfaceId = GetInterfaceId(interface); - return Browse(context, callback, interfaceId, regtype.c_str(), protocol); + return Browse(context, callback, interfaceId, regtype.c_str(), protocol, browseIdentifier); +} + +CHIP_ERROR ChipDnssdStopBrowse(intptr_t browseIdentifier) +{ + auto ctx = reinterpret_cast(browseIdentifier); + if (MdnsContexts::GetInstance().Has(ctx) != CHIP_NO_ERROR) + { + return CHIP_ERROR_NOT_FOUND; + } + + // We know this is an actual context now, so can check the type. + if (ctx->type != ContextType::Browse) + { + // stale pointer that got reallocated. + return CHIP_ERROR_NOT_FOUND; + } + + // Just treat this as a timeout error. Don't bother delivering the partial + // results we have queued up in the BrowseContext, if any. In practice + // there shouldn't be anything there long-term anyway. + auto browseCtx = static_cast(ctx); + browseCtx->Finalize(kDNSServiceErr_Timeout); + return CHIP_NO_ERROR; } CHIP_ERROR ChipDnssdResolve(DnssdService * service, chip::Inet::InterfaceId interface, DnssdResolveCallback callback, diff --git a/src/platform/Darwin/DnssdImpl.h b/src/platform/Darwin/DnssdImpl.h index b60a8c97c6bc90..2c4e5c84a2618e 100644 --- a/src/platform/Darwin/DnssdImpl.h +++ b/src/platform/Darwin/DnssdImpl.h @@ -117,6 +117,9 @@ struct BrowseContext : public GenericContext void DispatchFailure(DNSServiceErrorType err) override; void DispatchSuccess() override; + + // Dispatch what we have found so far, but don't stop browsing. + void DispatchPartialSuccess(); }; struct InterfaceInfo diff --git a/src/platform/ESP32/DnssdImpl.cpp b/src/platform/ESP32/DnssdImpl.cpp index 9dab2999bca927..342ce11a8c3015 100644 --- a/src/platform/ESP32/DnssdImpl.cpp +++ b/src/platform/ESP32/DnssdImpl.cpp @@ -459,7 +459,8 @@ void MdnsQueryNotifier(mdns_search_once_t * searchHandle) } CHIP_ERROR ChipDnssdBrowse(const char * type, DnssdServiceProtocol protocol, chip::Inet::IPAddressType addressType, - chip::Inet::InterfaceId interface, DnssdBrowseCallback callback, void * context) + chip::Inet::InterfaceId interface, DnssdBrowseCallback callback, void * context, + intptr_t * browseIdentifier) { CHIP_ERROR error = CHIP_NO_ERROR; mdns_search_once_t * searchHandle = @@ -477,9 +478,18 @@ CHIP_ERROR ChipDnssdBrowse(const char * type, DnssdServiceProtocol protocol, chi { chip::Platform::Delete(ctx); } + else + { + *browseIdentifier = reinterpret_cast(nullptr); + } return error; } +CHIP_ERROR ChipDnssdStopBrowse(intptr_t browseIdentifier) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + CHIP_ERROR ChipDnssdResolve(DnssdService * service, chip::Inet::InterfaceId interface, DnssdResolveCallback callback, void * context) { diff --git a/src/platform/Linux/DnssdImpl.cpp b/src/platform/Linux/DnssdImpl.cpp index 04e2eecc6165f7..758fa1569dd8a9 100644 --- a/src/platform/Linux/DnssdImpl.cpp +++ b/src/platform/Linux/DnssdImpl.cpp @@ -850,11 +850,18 @@ CHIP_ERROR ChipDnssdFinalizeServiceUpdate() } CHIP_ERROR ChipDnssdBrowse(const char * type, DnssdServiceProtocol protocol, chip::Inet::IPAddressType addressType, - chip::Inet::InterfaceId interface, DnssdBrowseCallback callback, void * context) + chip::Inet::InterfaceId interface, DnssdBrowseCallback callback, void * context, + intptr_t * browseIdentifier) { + *browseIdentifier = reinterpret_cast(nullptr); return MdnsAvahi::GetInstance().Browse(type, protocol, addressType, interface, callback, context); } +CHIP_ERROR ChipDnssdStopBrowse(intptr_t browseIdentifier) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + CHIP_ERROR ChipDnssdResolve(DnssdService * browseResult, chip::Inet::InterfaceId interface, DnssdResolveCallback callback, void * context) diff --git a/src/platform/OpenThread/DnssdImpl.cpp b/src/platform/OpenThread/DnssdImpl.cpp index 0a0f3e47d0939f..654b7cab5054b4 100644 --- a/src/platform/OpenThread/DnssdImpl.cpp +++ b/src/platform/OpenThread/DnssdImpl.cpp @@ -86,7 +86,7 @@ CHIP_ERROR ChipDnssdFinalizeServiceUpdate() } CHIP_ERROR ChipDnssdBrowse(const char * type, DnssdServiceProtocol protocol, Inet::IPAddressType addressType, - Inet::InterfaceId interface, DnssdBrowseCallback callback, void * context) + Inet::InterfaceId interface, DnssdBrowseCallback callback, void * context, intptr_t * browseIdentifier) { #if CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT && CHIP_DEVICE_CONFIG_ENABLE_THREAD_DNS_CLIENT if (type == nullptr || callback == nullptr) @@ -95,12 +95,18 @@ CHIP_ERROR ChipDnssdBrowse(const char * type, DnssdServiceProtocol protocol, Ine char serviceType[Dnssd::kDnssdFullTypeAndProtocolMaxSize + 1]; // +1 for null-terminator snprintf(serviceType, sizeof(serviceType), "%s.%s", type, GetProtocolString(protocol)); + *browseIdentifier = reinterpret_cast(nullptr); return ThreadStackMgr().DnsBrowse(serviceType, callback, context); #else return CHIP_ERROR_NOT_IMPLEMENTED; #endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT && CHIP_DEVICE_CONFIG_ENABLE_THREAD_DNS_CLIENT } +CHIP_ERROR ChipDnssdStopBrowse(intptr_t browseIdentifier) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + CHIP_ERROR ChipDnssdResolve(DnssdService * browseResult, Inet::InterfaceId interface, DnssdResolveCallback callback, void * context) { #if CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT && CHIP_DEVICE_CONFIG_ENABLE_THREAD_DNS_CLIENT diff --git a/src/platform/Tizen/DnssdImpl.cpp b/src/platform/Tizen/DnssdImpl.cpp index 40a3e23e4f9b49..68cf37e058faf4 100644 --- a/src/platform/Tizen/DnssdImpl.cpp +++ b/src/platform/Tizen/DnssdImpl.cpp @@ -783,12 +783,15 @@ CHIP_ERROR ChipDnssdFinalizeServiceUpdate() } CHIP_ERROR ChipDnssdBrowse(const char * type, DnssdServiceProtocol protocol, chip::Inet::IPAddressType addressType, - chip::Inet::InterfaceId interface, DnssdBrowseCallback callback, void * context) + chip::Inet::InterfaceId interface, DnssdBrowseCallback callback, void * context, + intptr_t * browseIdentifier) { VerifyOrReturnError(type != nullptr, CHIP_ERROR_INVALID_ARGUMENT); VerifyOrReturnError(IsSupportedProtocol(protocol), CHIP_ERROR_INVALID_ARGUMENT); VerifyOrReturnError(callback != nullptr, CHIP_ERROR_INVALID_ARGUMENT); + *browseIdentifier = reinterpret_cast(nullptr); + #if CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT && CHIP_DEVICE_CONFIG_ENABLE_THREAD_DNS_CLIENT if (DeviceLayer::ThreadStackMgr().IsThreadEnabled()) { @@ -800,6 +803,11 @@ CHIP_ERROR ChipDnssdBrowse(const char * type, DnssdServiceProtocol protocol, chi return DnssdTizen::GetInstance().Browse(type, protocol, addressType, interface, callback, context); } +CHIP_ERROR ChipDnssdStopBrowse(intptr_t browseIdentifier) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + CHIP_ERROR ChipDnssdResolve(DnssdService * browseResult, chip::Inet::InterfaceId interface, DnssdResolveCallback callback, void * context) { diff --git a/src/platform/android/DnssdImpl.cpp b/src/platform/android/DnssdImpl.cpp index aadd0ba5468819..58183120b5f815 100644 --- a/src/platform/android/DnssdImpl.cpp +++ b/src/platform/android/DnssdImpl.cpp @@ -143,7 +143,7 @@ CHIP_ERROR ChipDnssdFinalizeServiceUpdate() } CHIP_ERROR ChipDnssdBrowse(const char * type, DnssdServiceProtocol protocol, Inet::IPAddressType addressType, - Inet::InterfaceId interface, DnssdBrowseCallback callback, void * context) + Inet::InterfaceId interface, DnssdBrowseCallback callback, void * context, intptr_t * browseIdentifier) { VerifyOrReturnError(type != nullptr && callback != nullptr, CHIP_ERROR_INVALID_ARGUMENT); VerifyOrReturnError(sBrowserObject != nullptr && sBrowseMethod != nullptr, CHIP_ERROR_INVALID_ARGUMENT); @@ -167,9 +167,15 @@ CHIP_ERROR ChipDnssdBrowse(const char * type, DnssdServiceProtocol protocol, Ine return CHIP_JNI_ERROR_EXCEPTION_THROWN; } + *browseIdentifier = reinterpret_cast(nullptr); return CHIP_NO_ERROR; } +CHIP_ERROR ChipDnssdStopBrowse(intptr_t browseIdentifier) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + CHIP_ERROR ChipDnssdResolve(DnssdService * service, Inet::InterfaceId interface, DnssdResolveCallback callback, void * context) { VerifyOrReturnError(service != nullptr && callback != nullptr, CHIP_ERROR_INVALID_ARGUMENT); diff --git a/src/platform/bouffalolab/BL602/DnssdImpl.cpp b/src/platform/bouffalolab/BL602/DnssdImpl.cpp index 398bfbfa5caf65..143d19eb5cb374 100644 --- a/src/platform/bouffalolab/BL602/DnssdImpl.cpp +++ b/src/platform/bouffalolab/BL602/DnssdImpl.cpp @@ -296,7 +296,13 @@ CHIP_ERROR ChipDnssdFinalizeServiceUpdate() } CHIP_ERROR ChipDnssdBrowse(const char * /*type*/, DnssdServiceProtocol /*protocol*/, chip::Inet::IPAddressType addressType, - chip::Inet::InterfaceId /*interface*/, DnssdBrowseCallback /*callback*/, void * /*context*/) + chip::Inet::InterfaceId /*interface*/, DnssdBrowseCallback /*callback*/, void * /*context*/, + intptr_t * /*browseIdentifier*/) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +CHIP_ERROR ChipDnssdStopBrowse(intptr_t /*browseIdentifier*/) { return CHIP_ERROR_NOT_IMPLEMENTED; } diff --git a/src/platform/fake/DnssdImpl.cpp b/src/platform/fake/DnssdImpl.cpp index 8886d99bfab918..7fcc82c7bc8931 100644 --- a/src/platform/fake/DnssdImpl.cpp +++ b/src/platform/fake/DnssdImpl.cpp @@ -114,7 +114,13 @@ CHIP_ERROR ChipDnssdFinalizeServiceUpdate() } CHIP_ERROR ChipDnssdBrowse(const char * type, DnssdServiceProtocol protocol, chip::Inet::IPAddressType addressType, - chip::Inet::InterfaceId interface, DnssdBrowseCallback callback, void * context) + chip::Inet::InterfaceId interface, DnssdBrowseCallback callback, void * context, + intptr_t * browseIdentifier) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +CHIP_ERROR ChipDnssdStopBrowse(intptr_t browseIdentifier) { return CHIP_ERROR_NOT_IMPLEMENTED; } diff --git a/src/platform/mt793x/DnssdImpl.cpp b/src/platform/mt793x/DnssdImpl.cpp index 2934bce9184161..a88eeac1c62463 100644 --- a/src/platform/mt793x/DnssdImpl.cpp +++ b/src/platform/mt793x/DnssdImpl.cpp @@ -212,7 +212,8 @@ void ChipDNSServiceBrowseReply(DNSServiceRef sdRef, DNSServiceFlags flags, uint3 } CHIP_ERROR ChipDnssdBrowse(const char * type, DnssdServiceProtocol protocol, chip::Inet::IPAddressType addressType, - chip::Inet::InterfaceId interface, DnssdBrowseCallback callback, void * context) + chip::Inet::InterfaceId interface, DnssdBrowseCallback callback, void * context, + intptr_t * browseIdentifier) { CHIP_ERROR error = CHIP_NO_ERROR; DNSServiceErrorType err; @@ -229,9 +230,18 @@ CHIP_ERROR ChipDnssdBrowse(const char * type, DnssdServiceProtocol protocol, chi { error = CHIP_ERROR_INTERNAL; } + else + { + *browseIdentifier = reinterpret_cast(nullptr); + } return error; } +CHIP_ERROR ChipDnssdStopBrowse(intptr_t browseIdentifier) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + static DNSServiceRef ResolveClient = NULL; void ChipDNSServiceResolveReply(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, diff --git a/src/platform/tests/TestDnssd.cpp b/src/platform/tests/TestDnssd.cpp index 75fc48537b8231..fe7312fff8d7c9 100644 --- a/src/platform/tests/TestDnssd.cpp +++ b/src/platform/tests/TestDnssd.cpp @@ -96,8 +96,9 @@ static void InitCallback(void * context, CHIP_ERROR error) service.mSubTypeSize = 0; NL_TEST_ASSERT(suite, ChipDnssdPublishService(&service, HandlePublish) == CHIP_NO_ERROR); + intptr_t browseIdentifier; ChipDnssdBrowse("_mock", DnssdServiceProtocol::kDnssdProtocolTcp, chip::Inet::IPAddressType::kAny, - chip::Inet::InterfaceId::Null(), HandleBrowse, suite); + chip::Inet::InterfaceId::Null(), HandleBrowse, suite, &browseIdentifier); } static void ErrorCallback(void * context, CHIP_ERROR error) diff --git a/src/platform/webos/DnssdImpl.cpp b/src/platform/webos/DnssdImpl.cpp index f6dca795bf28da..043d6bb01c7020 100644 --- a/src/platform/webos/DnssdImpl.cpp +++ b/src/platform/webos/DnssdImpl.cpp @@ -847,11 +847,18 @@ CHIP_ERROR ChipDnssdFinalizeServiceUpdate() } CHIP_ERROR ChipDnssdBrowse(const char * type, DnssdServiceProtocol protocol, chip::Inet::IPAddressType addressType, - chip::Inet::InterfaceId interface, DnssdBrowseCallback callback, void * context) + chip::Inet::InterfaceId interface, DnssdBrowseCallback callback, void * context, + intptr_t * browseIdentifier) { + *browseIdentifier = reinterpret_cast(nullptr); return MdnsAvahi::GetInstance().Browse(type, protocol, addressType, interface, callback, context); } +CHIP_ERROR ChipDnssdStopBrowse(intptr_t browseIdentifier) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + CHIP_ERROR ChipDnssdResolve(DnssdService * browseResult, chip::Inet::InterfaceId interface, DnssdResolveCallback callback, void * context) From 3f8da8dc7b7891c3f5f43466fdfb9bee2e078050 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Tue, 4 Oct 2022 16:24:22 -0400 Subject: [PATCH 05/13] Remove Poll Control cluster from Door Lock (#22718) Poll control is a Zigbee feature. It doesn't exist in Matter. It is "O" conformance for door lock device type, but should have been "[Zigbee]" Co-authored-by: Andrei Litvin --- src/app/zap-templates/zcl/data-model/chip/matter-devices.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/src/app/zap-templates/zcl/data-model/chip/matter-devices.xml b/src/app/zap-templates/zcl/data-model/chip/matter-devices.xml index 9a0d228982d44a..1dfe3d554868c3 100644 --- a/src/app/zap-templates/zcl/data-model/chip/matter-devices.xml +++ b/src/app/zap-templates/zcl/data-model/chip/matter-devices.xml @@ -1392,7 +1392,6 @@ limitations under the License. BINDING - From 4f06a42213183ee8591e5f48315181e1bfa592d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20BOU=C3=89?= Date: Tue, 4 Oct 2022 23:43:49 +0200 Subject: [PATCH 06/13] Rename CHIP to Matter for ESP32 doc (#22768) * Rename CHIP to Matter for ESP32 * Rename CHIP to Matter for ESP32 Co-authored-by: Andrei Litvin --- examples/lock-app/esp32/README.md | 2 +- examples/temperature-measurement-app/esp32/README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/lock-app/esp32/README.md b/examples/lock-app/esp32/README.md index 0cf5c00c184644..f7f020ed10f702 100644 --- a/examples/lock-app/esp32/README.md +++ b/examples/lock-app/esp32/README.md @@ -1,4 +1,4 @@ -# CHIP ESP32 Lock Example +# Matter ESP32 Lock Example This example demonstrates the mapping of OnOff cluster to lock/unlock logic. diff --git a/examples/temperature-measurement-app/esp32/README.md b/examples/temperature-measurement-app/esp32/README.md index d89c12dada8800..567e302c6f8df8 100644 --- a/examples/temperature-measurement-app/esp32/README.md +++ b/examples/temperature-measurement-app/esp32/README.md @@ -1,4 +1,4 @@ -# CHIP ESP32 Temperature Sensor Example +# Matter ESP32 Temperature Sensor Example This example is meant to represent a minimal-sized application. From bcc99dd5f6d629271ec914a85439cf86603a74d7 Mon Sep 17 00:00:00 2001 From: jt5440 <102071042+jt5440@users.noreply.github.com> Date: Tue, 4 Oct 2022 19:47:21 -0400 Subject: [PATCH 07/13] Add files via upload --- docs/images/Matter_Arch_Overview.png | Bin 0 -> 136431 bytes docs/images/Matter_Layered_Arch.png | Bin 0 -> 113362 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 docs/images/Matter_Arch_Overview.png create mode 100644 docs/images/Matter_Layered_Arch.png diff --git a/docs/images/Matter_Arch_Overview.png b/docs/images/Matter_Arch_Overview.png new file mode 100644 index 0000000000000000000000000000000000000000..6521fa71ad451aacd1c9c9e2274e2ae98290f1eb GIT binary patch literal 136431 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 literal 0 HcmV?d00001 diff --git a/docs/images/Matter_Layered_Arch.png b/docs/images/Matter_Layered_Arch.png new file mode 100644 index 0000000000000000000000000000000000000000..38ad03ef437f38e88b7aacc27f0fb10f814e3143 GIT binary patch literal 113362 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

#13%Mp$(NR1v3BpM8cM$B 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 kG8kCR7P6}7JH&`TYRc|l7Og Date: Wed, 5 Oct 2022 00:47:30 -0400 Subject: [PATCH 08/13] Filter by vendor/product id (if available) in SetUpCodePairer. (#23019) * Filter by vendor/product id (if available) in SetUpCodePairer. If we have vendor/product information, from a QR code or long manual code, we should use that to filter out advertisements for other vendors or products. * Address review comment. --- src/controller/SetUpCodePairer.cpp | 42 +++++++++++++++++++++++------- src/controller/SetUpCodePairer.h | 10 ++++++- 2 files changed, 42 insertions(+), 10 deletions(-) diff --git a/src/controller/SetUpCodePairer.cpp b/src/controller/SetUpCodePairer.cpp index 3a7f218ea4821b..2f13f629a3e680 100644 --- a/src/controller/SetUpCodePairer.cpp +++ b/src/controller/SetUpCodePairer.cpp @@ -163,17 +163,20 @@ CHIP_ERROR SetUpCodePairer::StartDiscoverOverIP(SetupPayload & payload) auto & discriminator = payload.discriminator; if (discriminator.IsShortDiscriminator()) { - currentFilter.type = Dnssd::DiscoveryFilterType::kShortDiscriminator; - currentFilter.code = discriminator.GetShortValue(); + mCurrentFilter.type = Dnssd::DiscoveryFilterType::kShortDiscriminator; + mCurrentFilter.code = discriminator.GetShortValue(); } else { - currentFilter.type = Dnssd::DiscoveryFilterType::kLongDiscriminator; - currentFilter.code = discriminator.GetLongValue(); + mCurrentFilter.type = Dnssd::DiscoveryFilterType::kLongDiscriminator; + mCurrentFilter.code = discriminator.GetLongValue(); } + mPayloadVendorID = payload.vendorID; + mPayloadProductID = payload.productID; + // Handle possibly-sync callbacks. mWaitingForDiscovery[kIPTransport] = true; - CHIP_ERROR err = mCommissioner->DiscoverCommissionableNodes(currentFilter); + CHIP_ERROR err = mCommissioner->DiscoverCommissionableNodes(mCurrentFilter); if (err != CHIP_NO_ERROR) { mWaitingForDiscovery[kIPTransport] = false; @@ -186,7 +189,9 @@ CHIP_ERROR SetUpCodePairer::StopConnectOverIP() ChipLogDetail(Controller, "Stopping commissioning discovery over DNS-SD"); mWaitingForDiscovery[kIPTransport] = false; - currentFilter.type = Dnssd::DiscoveryFilterType::kNone; + mCurrentFilter.type = Dnssd::DiscoveryFilterType::kNone; + mPayloadVendorID = kNotAvailable; + mPayloadProductID = kNotAvailable; mCommissioner->StopCommissionableDiscovery(); return CHIP_NO_ERROR; @@ -286,6 +291,11 @@ void SetUpCodePairer::OnBLEDiscoveryError(CHIP_ERROR err) } #endif // CONFIG_NETWORK_LAYER_BLE +bool SetUpCodePairer::IdIsPresent(uint16_t vendorOrProductID) +{ + return vendorOrProductID != kNotAvailable; +} + bool SetUpCodePairer::NodeMatchesCurrentFilter(const Dnssd::DiscoveredNodeData & nodeData) const { if (nodeData.commissionData.commissioningMode == 0) @@ -293,12 +303,26 @@ bool SetUpCodePairer::NodeMatchesCurrentFilter(const Dnssd::DiscoveredNodeData & return false; } - switch (currentFilter.type) + // The advertisement may not include a vendor id. + if (IdIsPresent(mPayloadVendorID) && IdIsPresent(nodeData.commissionData.vendorId) && + mPayloadVendorID != nodeData.commissionData.vendorId) + { + return false; + } + + // The advertisement may not include a product id. + if (IdIsPresent(mPayloadProductID) && IdIsPresent(nodeData.commissionData.productId) && + mPayloadProductID != nodeData.commissionData.productId) + { + return false; + } + + switch (mCurrentFilter.type) { case Dnssd::DiscoveryFilterType::kShortDiscriminator: - return ((nodeData.commissionData.longDiscriminator >> 8) & 0x0F) == currentFilter.code; + return ((nodeData.commissionData.longDiscriminator >> 8) & 0x0F) == mCurrentFilter.code; case Dnssd::DiscoveryFilterType::kLongDiscriminator: - return nodeData.commissionData.longDiscriminator == currentFilter.code; + return nodeData.commissionData.longDiscriminator == mCurrentFilter.code; default: return false; } diff --git a/src/controller/SetUpCodePairer.h b/src/controller/SetUpCodePairer.h index 6a1381c9089a9b..ed1c6f0c2ad5ac 100644 --- a/src/controller/SetUpCodePairer.h +++ b/src/controller/SetUpCodePairer.h @@ -151,7 +151,15 @@ class DLL_EXPORT SetUpCodePairer : public DevicePairingDelegate #endif // CONFIG_NETWORK_LAYER_BLE bool NodeMatchesCurrentFilter(const Dnssd::DiscoveredNodeData & nodeData) const; - Dnssd::DiscoveryFilter currentFilter; + static bool IdIsPresent(uint16_t vendorOrProductID); + + Dnssd::DiscoveryFilter mCurrentFilter; + // The vendor id and product id from the SetupPayload. They may be 0, which + // indicates "not available" (e.g. because the SetupPayload came from a + // short manual code). In that case we should not filter on those values. + static constexpr uint16_t kNotAvailable = 0; + uint16_t mPayloadVendorID = kNotAvailable; + uint16_t mPayloadProductID = kNotAvailable; DeviceCommissioner * mCommissioner = nullptr; System::Layer * mSystemLayer = nullptr; From 55116a1259efb5f98893dfdedf6dad76b85c0288 Mon Sep 17 00:00:00 2001 From: markaj-nordic <98948394+markaj-nordic@users.noreply.github.com> Date: Wed, 5 Oct 2022 10:31:00 +0200 Subject: [PATCH 09/13] [scripts] created bootstrap script for ZAP (#22757) Extracted bootstrap code from run_zaptool.sh and reuse it in other Python scripts. This allows to run ZAP convert/generate tools out of the box without necessity to run zaptool beforehand. Signed-off-by: Marcin Kajor Signed-off-by: Marcin Kajor --- scripts/tools/zap/convert.py | 12 +++++- scripts/tools/zap/generate.py | 32 +++++++++++---- scripts/tools/zap/run_zaptool.sh | 12 +----- scripts/tools/zap/zap_bootstrap.sh | 64 ++++++++++++++++++++++++++++++ scripts/tools/zap_convert_all.py | 16 ++++++++ scripts/tools/zap_regen_all.py | 10 ++++- 6 files changed, 126 insertions(+), 20 deletions(-) create mode 100755 scripts/tools/zap/zap_bootstrap.sh diff --git a/scripts/tools/zap/convert.py b/scripts/tools/zap/convert.py index 1181ebe17d989f..f3b8fc1d1b76fe 100755 --- a/scripts/tools/zap/convert.py +++ b/scripts/tools/zap/convert.py @@ -60,11 +60,13 @@ def runArgumentsParser(): parser = argparse.ArgumentParser( description='Convert .zap files to the current zap version') parser.add_argument('zap', help='Path to the application .zap file') + parser.add_argument('--run-bootstrap', default=None, action='store_true', + help='Automatically run ZAP bootstrap. By default the bootstrap is not triggered') args = parser.parse_args() zap_file = getFilePath(args.zap) - return zap_file + return zap_file, args.run_bootstrap def detectZclFile(zapFile): @@ -96,11 +98,17 @@ def runConversion(zap_file): '-z', zcl_file, '-g', templates_file, '-o', zap_file, zap_file]) +def runBootstrap(): + subprocess.check_call(getFilePath("scripts/tools/zap/zap_bootstrap.sh"), shell=True) + + def main(): checkPythonVersion() + zap_file, run_bootstrap = runArgumentsParser() + if run_bootstrap: + runBootstrap() os.chdir(CHIP_ROOT_DIR) - zap_file = runArgumentsParser() runConversion(zap_file) diff --git a/scripts/tools/zap/generate.py b/scripts/tools/zap/generate.py index 5034390e373cd7..0885e83b5ee91e 100755 --- a/scripts/tools/zap/generate.py +++ b/scripts/tools/zap/generate.py @@ -22,6 +22,17 @@ import subprocess import sys import urllib.request +from dataclasses import dataclass + + +@dataclass +class CmdLineArgs: + zapFile: str + zclFile: str + templateFile: str + outputDir: str + runBootstrap: bool + CHIP_ROOT_DIR = os.path.realpath( os.path.join(os.path.dirname(__file__), '../../..')) @@ -77,7 +88,7 @@ def detectZclFile(zapFile): return getFilePath(path) -def runArgumentsParser(): +def runArgumentsParser() -> CmdLineArgs: default_templates = 'src/app/zap-templates/app-templates.json' default_output_dir = 'zap-generated/' @@ -90,6 +101,8 @@ def runArgumentsParser(): help='Path to the zcl templates records to use for generating artifacts (default: autodetect read from zap file)') parser.add_argument('-o', '--output-dir', default=None, help='Output directory for the generated files (default: automatically selected)') + parser.add_argument('--run-bootstrap', default=None, action='store_true', + help='Automatically run ZAP bootstrap. By default the bootstrap is not triggered') args = parser.parse_args() # By default, this script assumes that the global CHIP template is used with @@ -113,7 +126,7 @@ def runArgumentsParser(): templates_file = getFilePath(args.templates) output_dir = getDirPath(output_dir) - return (zap_file, zcl_file, templates_file, output_dir) + return CmdLineArgs(zap_file, zcl_file, templates_file, output_dir, args.run_bootstrap) def extractGeneratedIdl(output_dir, zap_config_path): @@ -209,13 +222,18 @@ def runJavaPrettifier(templates_file, output_dir): print('google-java-format error:', err) +def runBootstrap(): + subprocess.check_call(getFilePath("scripts/tools/zap/zap_bootstrap.sh"), shell=True) + + def main(): checkPythonVersion() - - # The maximum meory usage is over 4GB (#15620) + cmdLineArgs = runArgumentsParser() + if cmdLineArgs.runBootstrap: + runBootstrap() + # The maximum memory usage is over 4GB (#15620) os.environ["NODE_OPTIONS"] = "--max-old-space-size=8192" - zap_file, zcl_file, templates_file, output_dir = runArgumentsParser() - runGeneration(zap_file, zcl_file, templates_file, output_dir) + runGeneration(cmdLineArgs.zapFile, cmdLineArgs.zclFile, cmdLineArgs.templateFile, cmdLineArgs.outputDir) prettifiers = [ runClangPrettifier, @@ -223,7 +241,7 @@ def main(): ] for prettifier in prettifiers: - prettifier(templates_file, output_dir) + prettifier(cmdLineArgs.templateFile, cmdLineArgs.outputDir) if __name__ == '__main__': diff --git a/scripts/tools/zap/run_zaptool.sh b/scripts/tools/zap/run_zaptool.sh index 62a9d3de514bca..e2b7ee0a76e680 100755 --- a/scripts/tools/zap/run_zaptool.sh +++ b/scripts/tools/zap/run_zaptool.sh @@ -33,17 +33,9 @@ CHIP_ROOT="${SCRIPT_PATH%/scripts/tools/zap/run_zaptool.sh}" ( - cd "$CHIP_ROOT" && - git submodule update --init third_party/zap/repo + "$CHIP_ROOT"/scripts/tools/zap/zap_bootstrap.sh - cd "third_party/zap/repo" - if ! npm list installed-check &>/dev/null; then - npm install installed-check - fi - - if ! ./node_modules/.bin/installed-check -c &>/dev/null; then - npm install - fi + cd "$CHIP_ROOT/third_party/zap/repo" echo "ARGS: ${ZAP_ARGS[@]}" diff --git a/scripts/tools/zap/zap_bootstrap.sh b/scripts/tools/zap/zap_bootstrap.sh new file mode 100755 index 00000000000000..b4e459cb3e57b0 --- /dev/null +++ b/scripts/tools/zap/zap_bootstrap.sh @@ -0,0 +1,64 @@ +#!/bin/bash + +# +# 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. +# + +function _get_fullpath() { + cd "$(dirname "$1")" && echo "$PWD/$(basename "$1")" +} + +function _usage() { + cat < install and update required packages + zap_bootstrap.sh -c -> run a clean bootstrap, install packages from scratch +EOF + exit 1 +} + +set -e + +SCRIPT_PATH="$(_get_fullpath "$0")" +CHIP_ROOT="${SCRIPT_PATH%/scripts/tools/zap/zap_bootstrap.sh}" + +( + cd "$CHIP_ROOT" && + git submodule update --init third_party/zap/repo + + cd "third_party/zap/repo" + + if [ $# -eq 0 ]; then + echo "Running ZAP bootstrap" + if ! npm list installed-check &>/dev/null; then + npm install installed-check + fi + + if ! ./node_modules/.bin/installed-check -c &>/dev/null; then + npm install + fi + elif [ $# -eq 1 ] && [ "$1" = "-c" ]; then + echo "Running clean ZAP bootstrap" + npm ci + npm run version-stamp + npm rebuild canvas --update-binary + npm run build-spa + else + _usage + fi +) + +echo "ZAP bootstrap done!" diff --git a/scripts/tools/zap_convert_all.py b/scripts/tools/zap_convert_all.py index d32b3fa328b9c2..7ffb4454e3965b 100755 --- a/scripts/tools/zap_convert_all.py +++ b/scripts/tools/zap_convert_all.py @@ -19,6 +19,7 @@ from pathlib import Path import sys import subprocess +import argparse CHIP_ROOT_DIR = os.path.realpath( os.path.join(os.path.dirname(__file__), '../..')) @@ -53,8 +54,23 @@ def getTargets(): return targets +def runArgumentsParser(): + parser = argparse.ArgumentParser( + description='Convert all .zap files to the current zap version') + parser.add_argument('--run-bootstrap', default=None, action='store_true', + help='Automatically run ZAP bootstrap. By default the bootstrap is not triggered') + return parser.parse_args() + + +def runBootstrap(): + subprocess.check_call(os.path.join(CHIP_ROOT_DIR, "scripts/tools/zap/zap_bootstrap.sh"), shell=True) + + def main(): + args = runArgumentsParser() checkPythonVersion() + if args.run_bootstrap: + runBootstrap() os.chdir(CHIP_ROOT_DIR) targets = getTargets() diff --git a/scripts/tools/zap_regen_all.py b/scripts/tools/zap_regen_all.py index 23ead01804b0fa..db647387e2e61d 100755 --- a/scripts/tools/zap_regen_all.py +++ b/scripts/tools/zap_regen_all.py @@ -93,7 +93,9 @@ def setupArgumentsParser(): parser.add_argument('--tests', default='all', choices=['all', 'chip-tool', 'darwin-framework-tool', 'app1', 'app2'], help='When generating tests only target, Choose which tests to generate (default: all)') parser.add_argument('--dry-run', default=False, action='store_true', - help="Don't do any generationl just log what targets would be generated (default: False)") + help="Don't do any generation, just log what targets would be generated (default: False)") + parser.add_argument('--run-bootstrap', default=None, action='store_true', + help='Automatically run ZAP bootstrap. By default the bootstrap is not triggered') return parser.parse_args() @@ -224,6 +226,10 @@ def getTargets(type, test_target): return targets +def runBootstrap(): + subprocess.check_call(os.path.join(CHIP_ROOT_DIR, "scripts/tools/zap/zap_bootstrap.sh"), shell=True) + + def main(): logging.basicConfig( level=logging.INFO, @@ -236,6 +242,8 @@ def main(): targets = getTargets(args.type, args.tests) if (not args.dry_run): + if (args.run_bootstrap): + runBootstrap() for target in targets: target.generate() From a01d8e491a5fa4e45afaccb2c35a136c54fbe3c3 Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Wed, 5 Oct 2022 11:16:33 -0400 Subject: [PATCH 10/13] Reduce targets for cloudbuild smoketest (#23034) * Reduce targets for cloudbuild * Restyle * Add back missing build command * Make smoke tests runnable in cloudbuild-local after git changes (need also git lfs) * Make all directories safe --- integrations/cloudbuild/smoke-test.yaml | 64 ++++++++++++++++++++----- 1 file changed, 53 insertions(+), 11 deletions(-) diff --git a/integrations/cloudbuild/smoke-test.yaml b/integrations/cloudbuild/smoke-test.yaml index 1f855431754a1e..dd35d911e03997 100644 --- a/integrations/cloudbuild/smoke-test.yaml +++ b/integrations/cloudbuild/smoke-test.yaml @@ -1,10 +1,11 @@ steps: - - name: gcr.io/cloud-builders/git + - name: "connectedhomeip/chip-build-vscode:0.6.02" + entrypoint: 'bash' args: - - submodule - - update - - "--init" - - "--recursive" + - '-c' + - | + git config --global --add safe.directory "*" + git submodule update --init --recursive id: Submodules - name: "connectedhomeip/chip-build-vscode:0.6.02" env: @@ -27,9 +28,14 @@ steps: - PW_ENVIRONMENT_ROOT=/pwenv args: - >- - ./scripts/build/build_examples.py --enable-flashbundle - --target-glob '*-m5stack-*' build --create-archives - /workspace/artifacts/ + ./scripts/build/build_examples.py + --enable-flashbundle + --target esp32-m5stack-all-clusters-ipv6only + --target esp32-m5stack-all-clusters-minimal-rpc-ipv6only + --target esp32-m5stack-all-clusters-rpc + --target esp32-m5stack-ota-requestor + build + --create-archives /workspace/artifacts/ waitFor: - Bootstrap entrypoint: ./scripts/run_in_build_env.sh @@ -77,9 +83,45 @@ steps: - PW_ENVIRONMENT_ROOT=/pwenv args: - >- - ./scripts/build/build_examples.py --enable-flashbundle - --target-glob 'linux-*' --skip-target-glob '*-tests*' build - --create-archives /workspace/artifacts/ + ./scripts/build/build_examples.py + --enable-flashbundle + --target linux-arm64-clang-all-clusters + --target linux-arm64-clang-all-clusters-app-nodeps-ipv6only + --target linux-arm64-clang-all-clusters-minimal-ipv6only + --target linux-arm64-clang-bridge-ipv6only + --target linux-arm64-clang-chip-tool-ipv6only + --target linux-arm64-clang-chip-tool-nodeps-ipv6only + --target linux-arm64-clang-dynamic-bridge-ipv6only + --target linux-arm64-clang-light-rpc-ipv6only + --target linux-arm64-clang-lock-ipv6only + --target linux-arm64-clang-minmdns + --target linux-arm64-clang-ota-provider-nodeps-ipv6only + --target linux-arm64-clang-ota-requestor-nodeps-ipv6only + --target linux-arm64-clang-python-bindings + --target linux-arm64-clang-shell-ipv6only + --target linux-arm64-clang-thermostat-ipv6only + --target linux-arm64-clang-tv-app-ipv6only + --target linux-arm64-clang-tv-casting-app-ipv6only + --target linux-x64-address-resolve-tool + --target linux-x64-all-clusters-app-nodeps-ipv6only + --target linux-x64-all-clusters-coverage + --target linux-x64-bridge-ipv6only + --target linux-x64-chip-cert + --target linux-x64-chip-tool-ipv6only + --target linux-x64-dynamic-bridge-ipv6only + --target linux-x64-light-rpc-ipv6only + --target linux-x64-lock-ipv6only + --target linux-x64-minmdns-ipv6only + --target linux-x64-ota-provider-ipv6only + --target linux-x64-ota-requestor-ipv6only + --target linux-x64-python-bindings + --target linux-x64-rpc-console + --target linux-x64-shell-ipv6only + --target linux-x64-thermostat-ipv6only + --target linux-x64-tv-app-ipv6only + --target linux-x64-tv-casting-app-ipv6only + build + --create-archives /workspace/artifacts/ waitFor: - Bootstrap - EFR32 From faad9e179293775110f09692cd1c28e0d71b792f Mon Sep 17 00:00:00 2001 From: Evgeny Margolis Date: Wed, 5 Oct 2022 10:09:59 -0700 Subject: [PATCH 11/13] Updated CSA Official CD Signing Certificates (#23027) --- .../CSA_Matter_CD_Signing_Key_001.cert.der | Bin 0 -> 523 bytes .../CSA_Matter_CD_Signing_Key_001.cert.pem | 13 ++ .../CSA_Matter_CD_Signing_Key_002.cert.der | Bin 0 -> 524 bytes .../CSA_Matter_CD_Signing_Key_002.cert.pem | 13 ++ .../CSA_Matter_CD_Signing_Key_003.cert.der | Bin 0 -> 522 bytes .../CSA_Matter_CD_Signing_Key_003.cert.pem | 13 ++ .../CSA_Matter_CD_Signing_Key_004.cert.der | Bin 0 -> 522 bytes .../CSA_Matter_CD_Signing_Key_004.cert.pem | 13 ++ .../CSA_Matter_CD_Signing_Key_005.cert.der | Bin 0 -> 523 bytes .../CSA_Matter_CD_Signing_Key_005.cert.pem | 13 ++ ...tter_Certificate_and_Testing_Root.cert.der | Bin 0 -> 517 bytes ...tter_Certificate_and_Testing_Root.cert.pem | 13 ++ .../cd-certs/Chip-Test-CD-Cert.pem | 12 ++ .../credentials/TestHarnessDACProvider.cpp | 22 +-- .../DefaultDeviceAttestationVerifier.cpp | 155 +++++++++++++++--- .../DeviceAttestationCredsExample.cpp | 24 +-- 16 files changed, 248 insertions(+), 43 deletions(-) create mode 100644 credentials/development/cd-certs/CSA_Matter_CD_Signing_Key_001.cert.der create mode 100644 credentials/development/cd-certs/CSA_Matter_CD_Signing_Key_001.cert.pem create mode 100644 credentials/development/cd-certs/CSA_Matter_CD_Signing_Key_002.cert.der create mode 100644 credentials/development/cd-certs/CSA_Matter_CD_Signing_Key_002.cert.pem create mode 100644 credentials/development/cd-certs/CSA_Matter_CD_Signing_Key_003.cert.der create mode 100644 credentials/development/cd-certs/CSA_Matter_CD_Signing_Key_003.cert.pem create mode 100644 credentials/development/cd-certs/CSA_Matter_CD_Signing_Key_004.cert.der create mode 100644 credentials/development/cd-certs/CSA_Matter_CD_Signing_Key_004.cert.pem create mode 100644 credentials/development/cd-certs/CSA_Matter_CD_Signing_Key_005.cert.der create mode 100644 credentials/development/cd-certs/CSA_Matter_CD_Signing_Key_005.cert.pem create mode 100644 credentials/development/cd-certs/CSA_Matter_Certificate_and_Testing_Root.cert.der create mode 100644 credentials/development/cd-certs/CSA_Matter_Certificate_and_Testing_Root.cert.pem create mode 100644 credentials/development/cd-certs/Chip-Test-CD-Cert.pem diff --git a/credentials/development/cd-certs/CSA_Matter_CD_Signing_Key_001.cert.der b/credentials/development/cd-certs/CSA_Matter_CD_Signing_Key_001.cert.der new file mode 100644 index 0000000000000000000000000000000000000000..0bcdc2c37db44bb15611c557ddc62233c3a18d9a GIT binary patch literal 523 zcmXqLVq!OFVqCj`nTe5!i9NYEF*zmM(144LL#xf>oGlA8lR=On50K9s%EHCN>>TW9 zsAHf7;xY3m`zDr@q!uYSrxulDre!84mSpDVDJ15lD1@XImt^LpD>yqEiWms7acQ$L zvM@F+s$pW}VR1HfG%!#Q=QT1iG%zqWv^26XHI0(sH!?6cGO#ol>e*dY6B^(A(+xBeSV5b*?9e6fbI6m(g#&drId+ zG0mMj{l9ORsku1KAO+}M=1^H-M#ldv90qJaiiwfIfDa_b4-x|gC}W#}EQrs?BE}-} z&%}P}O!qSD#CNWi!on7w{?BUr4CF!5$}AEFVhtkGpJZM*$|7GH}KS?8SVKgUQjDKdOqw4=kt?QUd!9bazS1oB&@HPAAv2q90s!u1qR{{V literal 0 HcmV?d00001 diff --git a/credentials/development/cd-certs/CSA_Matter_CD_Signing_Key_001.cert.pem b/credentials/development/cd-certs/CSA_Matter_CD_Signing_Key_001.cert.pem new file mode 100644 index 00000000000000..93697332c9f692 --- /dev/null +++ b/credentials/development/cd-certs/CSA_Matter_CD_Signing_Key_001.cert.pem @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE----- +MIICBzCCAa2gAwIBAgIHY3NhY2RrMTAKBggqhkjOPQQDAjBSMQwwCgYDVQQKDAND +U0ExLDAqBgNVBAMMI01hdHRlciBDZXJ0aWZpY2F0aW9uIGFuZCBUZXN0aW5nIENB +MRQwEgYKKwYBBAGConwCAQwEQzVBMDAgFw0yMjEwMDMxOTI4NTVaGA8yMDcyMDky +MDE5Mjg1NVowWDEMMAoGA1UECgwDQ1NBMTIwMAYDVQQDDClDZXJ0aWZpY2F0aW9u +IERlY2xhcmF0aW9uIFNpZ25pbmcgS2V5IDAwMTEUMBIGCisGAQQBgqJ8AgEMBEM1 +QTAwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATN7uk+RPi3K+PRqcB+IZaLmv/z +tAPwXhZp17Hlyu5vx3FLQufiNpXpLNdjVHOigK5ojze7lInhFim5uU/3sJkpo2Yw +ZDASBgNVHRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQU +/jQ/lZlHdjth7kU5ExM4SU/mfY4wHwYDVR0jBBgwFoAUl+Rp0MUEFMJvxwH3fpR3 +OQmN9qUwCgYIKoZIzj0EAwIDSAAwRQIgEDWOcdKsVGtUh3evHbBd1lq4aS7yQtOp +6GrOQ3/zXBsCIQDxorh2RXSaI8m2RCcoWaiWa0nLzQepNm3C2jrQVJmC2Q== +-----END CERTIFICATE----- diff --git a/credentials/development/cd-certs/CSA_Matter_CD_Signing_Key_002.cert.der b/credentials/development/cd-certs/CSA_Matter_CD_Signing_Key_002.cert.der new file mode 100644 index 0000000000000000000000000000000000000000..3e6046ac47a8b08cd49421a48961ec1c952c13e4 GIT binary patch literal 524 zcmXqLV&X7pVqCj`nTe5!i9NYEF*zmM$bgHDL#xf>oGlA8lR=On50K9s%EHCN>>TW9 zsAHf7;xY3m`zDr@q!uYSrxulDre!84mSpDVDJ15lD1@XImt^LpD>yqEiWms7acQ$L zvM@F+s$pW}VR1HfG%!#Q=QT1iG%zqWv@|v|F^iJmH!?6cGO#oct{Z3eO+J|Bx1i^yG; z+Y!-IB4HrbATs?)=7pmyB8T#iGk&j|Qf|rF`)w(5 z^e}re7`QPhGR%5+UaaQwa{fQN1TJqr`&~e~XL~{5%FuQf`Qx<~zWd97N+!Q}UZ1u0 goGlA8lR=On50K9s%EHCN>>TW9 zsAHf7;xY3m`zDr@q!uYSrxulDre!84mSpDVDJ15lD1@XImt^LpD>yqEiWms7acQ$L zvM@F+s$pW}VR1HfG%!#Q=QT1iG%zqWv@|g^FpQGmH!?6cGO#o#26n2jCmJ0?b`H<=mPnVlF|=7+~z{kuI# zUSP?6!wMW@Rikd(Mk->luB*qUC0|qE#n}IBd&&MLhBH}J! z`uu?3sulZce0_u;KRLuXb%nQqJV;uZMZ!R=L1g-q%nL_ZL=NR2XZ&6_rQDLU_uEqB z=wWteFmPc~Pzaxs+rM>YsPAgQzrPRhu%BO(`MpSCsu|O&wdsGXnSd%PrcQ0S#Z{Cu dH?O|v$6v`$`fuF66q%oGlA8lR=On50K9s%EHCN>>TW9 zsAHf7;xY3m`zDr@q!uYSrxulDre!84mSpDVDJ15lD1@XImt^LpD>yqEiWms7acQ$L zvM@F+s$pW}VR1HfG%!#Q=QT1iG%zqWv@|g`GK`YoH!?6cGO#oe;yle!^^b z%M_MsTojYxUYur-0`x9(sH`v}<9`+o12!PV#K>U42NL54i2(zYvCTjh#OGrXV-fk* z#=JOFZ-zjTUk28L+n^JDc+52rN za`Z5}GZ?rqDd;VbpSasQu|3V{sm?n{G$XuCnc8Qt;O}(fB4z fILPO_^t~LxoGlA8lR=On50K9s%EHCN>>TW9 zsAHf7;xY3m`zDr@q!uYSrxulDre!84mSpDVDJ15lD1@XImt^LpD>yqEiWms7acQ$L zvM@F+s$pW}VR1HfG%!#Q=QT1iG%zqWv@|g{G>wwrH!?6cGO#o!C>IZq{wjA-D&m{nKj-jGSf2E7;ME7+6$64$BQvWta^L?*>*z)CWT0A&(P{6 g8sAj-6+~xd#?*U%6Eb<9r*UonvX6OpoGlA8lR=On50K9s%EHCN>>TW9 zsAHf7;xY3m`zDr@q!uYSrxulDre!84mSpDVDJ15lD1@XImt^LpD>yqEiWms7acQ$L zvM@F+s$pW}VR1HfG%!#Q=QT1iFgGwav^26XFo}}jH!=hYm>C*F1!!Vxq=7ISJJ?@L zj8G3UGqN)~F|b&8Ssh*#yYF-n|1(8do3$QE`QHT>ESWTa?Tv&VkIMfaxF>J7&A7^> zr8>%rHE%^B-{kUlZ{MkkGylD5%BXs}&tq|#K?=~L%%QTvjEw(TI1Jc;6cZz(0Ut<= zA0!40N=7yVSrDI(MT|vc`jgBHM_EJ;M6VXA@%-{1@kr@SbTTNM~x-Q-QP@|_9-_Dg?Ic)VNzsxzsI1fd#8SX dO9fkF&;!v(2~CSL^DUyg<9*HFeZCo(3jkSUn}PrU literal 0 HcmV?d00001 diff --git a/credentials/development/cd-certs/CSA_Matter_Certificate_and_Testing_Root.cert.pem b/credentials/development/cd-certs/CSA_Matter_Certificate_and_Testing_Root.cert.pem new file mode 100644 index 00000000000000..5a003156fd6c65 --- /dev/null +++ b/credentials/development/cd-certs/CSA_Matter_Certificate_and_Testing_Root.cert.pem @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE----- +MIICATCCAaegAwIBAgIHY3Nhcm9vdDAKBggqhkjOPQQDAjBSMQwwCgYDVQQKDAND +U0ExLDAqBgNVBAMMI01hdHRlciBDZXJ0aWZpY2F0aW9uIGFuZCBUZXN0aW5nIENB +MRQwEgYKKwYBBAGConwCAQwEQzVBMDAgFw0yMjA3MDcxOTI4MDRaGA8yMTIyMDYx +MzE5MjgwNFowUjEMMAoGA1UECgwDQ1NBMSwwKgYDVQQDDCNNYXR0ZXIgQ2VydGlm +aWNhdGlvbiBhbmQgVGVzdGluZyBDQTEUMBIGCisGAQQBgqJ8AgEMBEM1QTAwWTAT +BgcqhkjOPQIBBggqhkjOPQMBBwNCAAQ4SjrDql2+y3IP5iEdPK1IYm/3EaCkkp+t +2GD44nf/wN4fPrYzejSEe1o6BW6ocQ6Td+7t7iUXA/3ZNQEly45Io2YwZDASBgNV +HRMBAf8ECDAGAQH/AgEBMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUl+Rp0MUE +FMJvxwH3fpR3OQmN9qUwHwYDVR0jBBgwFoAUl+Rp0MUEFMJvxwH3fpR3OQmN9qUw +CgYIKoZIzj0EAwIDSAAwRQIgearlB0fCJ49UoJ6xwKPdlPEopCOL9jVCviODEleI ++mQCIQDvvDCKi7kvj4R4BoFS4BVZGCk4zJ84W4tfTTfu89lRbQ== +-----END CERTIFICATE----- diff --git a/credentials/development/cd-certs/Chip-Test-CD-Cert.pem b/credentials/development/cd-certs/Chip-Test-CD-Cert.pem new file mode 100644 index 00000000000000..0392cd2b6a5dd6 --- /dev/null +++ b/credentials/development/cd-certs/Chip-Test-CD-Cert.pem @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE----- +MIIBszCCAVqgAwIBAgIIRdrzneR6oI8wCgYIKoZIzj0EAwIwKzEpMCcGA1UEAwwg +TWF0dGVyIFRlc3QgQ0QgU2lnbmluZyBBdXRob3JpdHkwIBcNMjEwNjI4MTQyMzQz +WhgPOTk5OTEyMzEyMzU5NTlaMCsxKTAnBgNVBAMMIE1hdHRlciBUZXN0IENEIFNp +Z25pbmcgQXV0aG9yaXR5MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEPDmJIkUr +VcrzicJb0bykZWlSzLkOiGkkmthHRlMBTL+V1oeWXgNrUhxRA35rjO3vyh60QEZp +T6CIgu7WUZ3suqNmMGQwEgYDVR0TAQH/BAgwBgEB/wIBATAOBgNVHQ8BAf8EBAMC +AQYwHQYDVR0OBBYEFGL6gjNZrPqplj4c+hQK3fUE83FgMB8GA1UdIwQYMBaAFGL6 +gjNZrPqplj4c+hQK3fUE83FgMAoGCCqGSM49BAMCA0cAMEQCICxUXOTkV9im8NnZ +u+vW7OHd/n+MbZps83UyH8b6xxOEAiBUB3jodDlyUn7t669YaGIgtUB48s1OYqdq +58u5L/VMiw== +-----END CERTIFICATE----- diff --git a/src/app/tests/suites/credentials/TestHarnessDACProvider.cpp b/src/app/tests/suites/credentials/TestHarnessDACProvider.cpp index 56b1b0edf8ef06..2940ec6c3d54a1 100644 --- a/src/app/tests/suites/credentials/TestHarnessDACProvider.cpp +++ b/src/app/tests/suites/credentials/TestHarnessDACProvider.cpp @@ -39,7 +39,7 @@ // 0x8048, 0x8049, 0x804A, 0x804B, 0x804C, 0x804D, 0x804E, 0x804F, 0x8050, 0x8051, 0x8052, 0x8053, 0x8054, 0x8055, 0x8056, // 0x8057, 0x8058, 0x8059, 0x805A, 0x805B, 0x805C, 0x805D, 0x805E, 0x805F, 0x8060, 0x8061, 0x8062, 0x8063 ] //-> device_type_id = 0x0016 -//-> certificate_id = "CSA00000MAT00000-00" +//-> certificate_id = "CSA00000SWC00000-00" //-> security_level = 0 //-> security_information = 0 //-> version_number = 1 @@ -47,8 +47,8 @@ //-> dac_origin_vendor_id is not present //-> dac_origin_product_id is not present constexpr const uint8_t kCdForAllExamples[540] = { - 0x30, 0x82, 0x02, 0x18, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x82, 0x02, 0x09, 0x30, 0x82, - 0x02, 0x05, 0x02, 0x01, 0x03, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x30, + 0x30, 0x82, 0x02, 0x17, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x82, 0x02, 0x08, 0x30, 0x82, + 0x02, 0x04, 0x02, 0x01, 0x03, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x30, 0x82, 0x01, 0x70, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, 0x01, 0x61, 0x04, 0x82, 0x01, 0x5d, 0x15, 0x24, 0x00, 0x01, 0x25, 0x01, 0xf1, 0xff, 0x36, 0x02, 0x05, 0x00, 0x80, 0x05, 0x01, 0x80, 0x05, 0x02, 0x80, 0x05, 0x03, 0x80, 0x05, 0x04, 0x80, 0x05, 0x05, 0x80, 0x05, 0x06, 0x80, 0x05, 0x07, 0x80, 0x05, 0x08, 0x80, 0x05, 0x09, 0x80, 0x05, @@ -65,14 +65,14 @@ constexpr const uint8_t kCdForAllExamples[540] = { 0x50, 0x80, 0x05, 0x51, 0x80, 0x05, 0x52, 0x80, 0x05, 0x53, 0x80, 0x05, 0x54, 0x80, 0x05, 0x55, 0x80, 0x05, 0x56, 0x80, 0x05, 0x57, 0x80, 0x05, 0x58, 0x80, 0x05, 0x59, 0x80, 0x05, 0x5a, 0x80, 0x05, 0x5b, 0x80, 0x05, 0x5c, 0x80, 0x05, 0x5d, 0x80, 0x05, 0x5e, 0x80, 0x05, 0x5f, 0x80, 0x05, 0x60, 0x80, 0x05, 0x61, 0x80, 0x05, 0x62, 0x80, 0x05, 0x63, 0x80, 0x18, 0x24, 0x03, 0x16, - 0x2c, 0x04, 0x13, 0x43, 0x53, 0x41, 0x30, 0x30, 0x30, 0x30, 0x30, 0x4d, 0x41, 0x54, 0x30, 0x30, 0x30, 0x30, 0x30, 0x2d, 0x30, - 0x30, 0x24, 0x05, 0x00, 0x24, 0x06, 0x00, 0x24, 0x07, 0x01, 0x24, 0x08, 0x00, 0x18, 0x31, 0x7d, 0x30, 0x7b, 0x02, 0x01, 0x03, - 0x80, 0x14, 0x83, 0xfa, 0xd7, 0x81, 0xe8, 0x2d, 0x01, 0x8b, 0x4f, 0x14, 0xf0, 0xa1, 0xc7, 0xf6, 0x84, 0x01, 0x8c, 0xc5, 0xd1, - 0x9f, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, - 0xce, 0x3d, 0x04, 0x03, 0x02, 0x04, 0x47, 0x30, 0x45, 0x02, 0x20, 0x57, 0xc4, 0xb8, 0x18, 0x3a, 0x93, 0xa6, 0xb8, 0xc3, 0x60, - 0x3e, 0x77, 0xde, 0x8e, 0xb1, 0x94, 0x8c, 0x9c, 0xc0, 0x50, 0x60, 0xa6, 0x1a, 0xa9, 0xd7, 0x43, 0xeb, 0xea, 0xf9, 0x5f, 0x73, - 0xc9, 0x02, 0x21, 0x00, 0xa3, 0xd5, 0xa1, 0x1f, 0xb0, 0x71, 0xf2, 0x13, 0xa5, 0xe1, 0x24, 0xed, 0xe7, 0xe1, 0xee, 0x16, 0x7e, - 0x19, 0xc2, 0x8c, 0x3d, 0xed, 0x98, 0x4c, 0xf1, 0x03, 0x96, 0x48, 0xe8, 0x8c, 0xd8, 0x06 + 0x2c, 0x04, 0x13, 0x43, 0x53, 0x41, 0x30, 0x30, 0x30, 0x30, 0x30, 0x53, 0x57, 0x43, 0x30, 0x30, 0x30, 0x30, 0x30, 0x2d, 0x30, + 0x30, 0x24, 0x05, 0x00, 0x24, 0x06, 0x00, 0x24, 0x07, 0x01, 0x24, 0x08, 0x00, 0x18, 0x31, 0x7c, 0x30, 0x7a, 0x02, 0x01, 0x03, + 0x80, 0x14, 0xfe, 0x34, 0x3f, 0x95, 0x99, 0x47, 0x76, 0x3b, 0x61, 0xee, 0x45, 0x39, 0x13, 0x13, 0x38, 0x49, 0x4f, 0xe6, 0x7d, + 0x8e, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, + 0xce, 0x3d, 0x04, 0x03, 0x02, 0x04, 0x46, 0x30, 0x44, 0x02, 0x20, 0x4a, 0x12, 0xf8, 0xd4, 0x2f, 0x90, 0x23, 0x5c, 0x05, 0xa7, + 0x71, 0x21, 0xcb, 0xeb, 0xae, 0x15, 0xd5, 0x90, 0x14, 0x65, 0x58, 0xe9, 0xc9, 0xb4, 0x7a, 0x1a, 0x38, 0xf7, 0xa3, 0x6a, 0x7d, + 0xc5, 0x02, 0x20, 0x20, 0xa4, 0x74, 0x28, 0x97, 0xc3, 0x0a, 0xed, 0xa0, 0xa5, 0x6b, 0x36, 0xe1, 0x4e, 0xbb, 0xc8, 0x5b, 0xbd, + 0xb7, 0x44, 0x93, 0xf9, 0x93, 0x58, 0x1e, 0xb0, 0x44, 0x4e, 0xd6, 0xca, 0x94, 0x0b }; namespace chip { diff --git a/src/credentials/attestation_verifier/DefaultDeviceAttestationVerifier.cpp b/src/credentials/attestation_verifier/DefaultDeviceAttestationVerifier.cpp index fc457521cc2570..70684157014515 100644 --- a/src/credentials/attestation_verifier/DefaultDeviceAttestationVerifier.cpp +++ b/src/credentials/attestation_verifier/DefaultDeviceAttestationVerifier.cpp @@ -128,32 +128,147 @@ constexpr uint8_t gCdRootCert[517] = { // Official CD "Signing Key 001" // // -----BEGIN CERTIFICATE----- -// MIICCDCCAa2gAwIBAgIHY3NhY2RzMTAKBggqhkjOPQQDAjBSMQwwCgYDVQQKDAND +// MIICBzCCAa2gAwIBAgIHY3NhY2RrMTAKBggqhkjOPQQDAjBSMQwwCgYDVQQKDAND // U0ExLDAqBgNVBAMMI01hdHRlciBDZXJ0aWZpY2F0aW9uIGFuZCBUZXN0aW5nIENB -// MRQwEgYKKwYBBAGConwCAQwEQzVBMDAgFw0yMjA4MTExOTMxMTVaGA8yMDcyMDcy -// OTE5MzExNVowWDEMMAoGA1UECgwDQ1NBMTIwMAYDVQQDDClDZXJ0aWZpY2F0aW9u +// MRQwEgYKKwYBBAGConwCAQwEQzVBMDAgFw0yMjEwMDMxOTI4NTVaGA8yMDcyMDky +// MDE5Mjg1NVowWDEMMAoGA1UECgwDQ1NBMTIwMAYDVQQDDClDZXJ0aWZpY2F0aW9u // IERlY2xhcmF0aW9uIFNpZ25pbmcgS2V5IDAwMTEUMBIGCisGAQQBgqJ8AgEMBEM1 -// QTAwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARbW8Ou1rqjg/3Pm51ac/rqfmXr -// WSfBxcArHPpLi9trm36yUlE/I/IqWDOdyK24gEYKySHTdte5cMUMO+bm0jbwo2Yw +// QTAwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATN7uk+RPi3K+PRqcB+IZaLmv/z +// tAPwXhZp17Hlyu5vx3FLQufiNpXpLNdjVHOigK5ojze7lInhFim5uU/3sJkpo2Yw // ZDASBgNVHRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQU -// g/rXgegtAYtPFPChx/aEAYzF0Z8wHwYDVR0jBBgwFoAUl+Rp0MUEFMJvxwH3fpR3 -// OQmN9qUwCgYIKoZIzj0EAwIDSQAwRgIhAIbSu8KoWTj5792UxtJ/uSgQXVTLRRsm -// 09ys2m37JxDvAiEA8WMKDbRbwOtkabIyqwDgmiR3KwkyYwaqN4GPsRKfxwQ= +// /jQ/lZlHdjth7kU5ExM4SU/mfY4wHwYDVR0jBBgwFoAUl+Rp0MUEFMJvxwH3fpR3 +// OQmN9qUwCgYIKoZIzj0EAwIDSAAwRQIgEDWOcdKsVGtUh3evHbBd1lq4aS7yQtOp +// 6GrOQ3/zXBsCIQDxorh2RXSaI8m2RCcoWaiWa0nLzQepNm3C2jrQVJmC2Q== // -----END CERTIFICATE----- // constexpr uint8_t gCdSigningKey001PubkeyBytes[65] = { - 0x04, 0x5b, 0x5b, 0xc3, 0xae, 0xd6, 0xba, 0xa3, 0x83, 0xfd, 0xcf, 0x9b, 0x9d, 0x5a, 0x73, 0xfa, 0xea, - 0x7e, 0x65, 0xeb, 0x59, 0x27, 0xc1, 0xc5, 0xc0, 0x2b, 0x1c, 0xfa, 0x4b, 0x8b, 0xdb, 0x6b, 0x9b, 0x7e, - 0xb2, 0x52, 0x51, 0x3f, 0x23, 0xf2, 0x2a, 0x58, 0x33, 0x9d, 0xc8, 0xad, 0xb8, 0x80, 0x46, 0x0a, 0xc9, - 0x21, 0xd3, 0x76, 0xd7, 0xb9, 0x70, 0xc5, 0x0c, 0x3b, 0xe6, 0xe6, 0xd2, 0x36, 0xf0 + 0x04, 0xcd, 0xee, 0xe9, 0x3e, 0x44, 0xf8, 0xb7, 0x2b, 0xe3, 0xd1, 0xa9, 0xc0, 0x7e, 0x21, 0x96, 0x8b, + 0x9a, 0xff, 0xf3, 0xb4, 0x03, 0xf0, 0x5e, 0x16, 0x69, 0xd7, 0xb1, 0xe5, 0xca, 0xee, 0x6f, 0xc7, 0x71, + 0x4b, 0x42, 0xe7, 0xe2, 0x36, 0x95, 0xe9, 0x2c, 0xd7, 0x63, 0x54, 0x73, 0xa2, 0x80, 0xae, 0x68, 0x8f, + 0x37, 0xbb, 0x94, 0x89, 0xe1, 0x16, 0x29, 0xb9, 0xb9, 0x4f, 0xf7, 0xb0, 0x99, 0x29 }; -constexpr uint8_t gCdSigningKey001Kid[20] = { 0x83, 0xfa, 0xd7, 0x81, 0xe8, 0x2d, 0x01, 0x8b, 0x4f, 0x14, - 0xf0, 0xa1, 0xc7, 0xf6, 0x84, 0x01, 0x8c, 0xc5, 0xd1, 0x9f }; +constexpr uint8_t gCdSigningKey001Kid[20] = { 0xFE, 0x34, 0x3F, 0x95, 0x99, 0x47, 0x76, 0x3B, 0x61, 0xEE, + 0x45, 0x39, 0x13, 0x13, 0x38, 0x49, 0x4F, 0xE6, 0x7D, 0x8E }; -std::array gCdKids = { ByteSpan{ gTestCdPubkeyKid }, ByteSpan{ gCdSigningKey001Kid } }; -std::array gCdPubkeys = { Crypto::P256PublicKey{ gTestCdPubkeyBytes }, - Crypto::P256PublicKey{ gCdSigningKey001PubkeyBytes } }; +// Official CD "Signing Key 002" +// +// -----BEGIN CERTIFICATE----- +// MIICCDCCAa2gAwIBAgIHY3NhY2RrMjAKBggqhkjOPQQDAjBSMQwwCgYDVQQKDAND +// U0ExLDAqBgNVBAMMI01hdHRlciBDZXJ0aWZpY2F0aW9uIGFuZCBUZXN0aW5nIENB +// MRQwEgYKKwYBBAGConwCAQwEQzVBMDAgFw0yMjEwMDMxOTM2NDZaGA8yMDcyMDky +// MDE5MzY0NlowWDEMMAoGA1UECgwDQ1NBMTIwMAYDVQQDDClDZXJ0aWZpY2F0aW9u +// IERlY2xhcmF0aW9uIFNpZ25pbmcgS2V5IDAwMjEUMBIGCisGAQQBgqJ8AgEMBEM1 +// QTAwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQDGTfo+UJRBF3ydFe7RiU+43VO +// jBKuKFV9gCe51MNW2RtAjP8yJ1AXsl+Mi6IFFtXIOvK3JBKAE9/Mj5XSAKkLo2Yw +// ZDASBgNVHRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQU +// 3QTbWFshTBxYFYfmVo30h7bdxwEwHwYDVR0jBBgwFoAUl+Rp0MUEFMJvxwH3fpR3 +// OQmN9qUwCgYIKoZIzj0EAwIDSQAwRgIhAJruzxZ806cP/LoQ07PN9xAbjLdwUalV +// h0Qfx304Tb92AiEAk+jnf2qtyfKyTEHpT3Xf3bfekqUOA+8ikB1yjL5oTsI= +// -----END CERTIFICATE----- +// +constexpr uint8_t gCdSigningKey002PubkeyBytes[65] = { + 0x04, 0x03, 0x19, 0x37, 0xe8, 0xf9, 0x42, 0x51, 0x04, 0x5d, 0xf2, 0x74, 0x57, 0xbb, 0x46, 0x25, 0x3e, + 0xe3, 0x75, 0x4e, 0x8c, 0x12, 0xae, 0x28, 0x55, 0x7d, 0x80, 0x27, 0xb9, 0xd4, 0xc3, 0x56, 0xd9, 0x1b, + 0x40, 0x8c, 0xff, 0x32, 0x27, 0x50, 0x17, 0xb2, 0x5f, 0x8c, 0x8b, 0xa2, 0x05, 0x16, 0xd5, 0xc8, 0x3a, + 0xf2, 0xb7, 0x24, 0x12, 0x80, 0x13, 0xdf, 0xcc, 0x8f, 0x95, 0xd2, 0x00, 0xa9, 0x0b +}; + +constexpr uint8_t gCdSigningKey002Kid[20] = { 0xDD, 0x04, 0xDB, 0x58, 0x5B, 0x21, 0x4C, 0x1C, 0x58, 0x15, + 0x87, 0xE6, 0x56, 0x8D, 0xF4, 0x87, 0xB6, 0xDD, 0xC7, 0x01 }; + +// Official CD "Signing Key 003" +// +// -----BEGIN CERTIFICATE----- +// MIICBjCCAa2gAwIBAgIHY3NhY2RrMzAKBggqhkjOPQQDAjBSMQwwCgYDVQQKDAND +// U0ExLDAqBgNVBAMMI01hdHRlciBDZXJ0aWZpY2F0aW9uIGFuZCBUZXN0aW5nIENB +// MRQwEgYKKwYBBAGConwCAQwEQzVBMDAgFw0yMjEwMDMxOTQxMDFaGA8yMDcyMDky +// MDE5NDEwMVowWDEMMAoGA1UECgwDQ1NBMTIwMAYDVQQDDClDZXJ0aWZpY2F0aW9u +// IERlY2xhcmF0aW9uIFNpZ25pbmcgS2V5IDAwMzEUMBIGCisGAQQBgqJ8AgEMBEM1 +// QTAwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASfV1zV/bdSHxCk3zHwc5ErYUco +// 8tN/W2uWvCy/fAsRlpBXfVVdIaCWYKiwgqM56lMPeoEthpO1b9dkGF+rzTL1o2Yw +// ZDASBgNVHRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQU +// RxA158BOqqi+fE1ME+PkwgmVqEswHwYDVR0jBBgwFoAUl+Rp0MUEFMJvxwH3fpR3 +// OQmN9qUwCgYIKoZIzj0EAwIDRwAwRAIgIFecbY+1mVVNqxH9+8IMB8+safdyIJU2 +// AqqtZ/w7AkQCIHiVlYTaCnJsnW5/cvj9GfIv7Eb0cjdmcAkrYGbnPQzX +// -----END CERTIFICATE----- +// +constexpr uint8_t gCdSigningKey003PubkeyBytes[65] = { + 0x04, 0x9f, 0x57, 0x5c, 0xd5, 0xfd, 0xb7, 0x52, 0x1f, 0x10, 0xa4, 0xdf, 0x31, 0xf0, 0x73, 0x91, 0x2b, + 0x61, 0x47, 0x28, 0xf2, 0xd3, 0x7f, 0x5b, 0x6b, 0x96, 0xbc, 0x2c, 0xbf, 0x7c, 0x0b, 0x11, 0x96, 0x90, + 0x57, 0x7d, 0x55, 0x5d, 0x21, 0xa0, 0x96, 0x60, 0xa8, 0xb0, 0x82, 0xa3, 0x39, 0xea, 0x53, 0x0f, 0x7a, + 0x81, 0x2d, 0x86, 0x93, 0xb5, 0x6f, 0xd7, 0x64, 0x18, 0x5f, 0xab, 0xcd, 0x32, 0xf5 +}; + +constexpr uint8_t gCdSigningKey003Kid[20] = { 0x47, 0x10, 0x35, 0xE7, 0xC0, 0x4E, 0xAA, 0xA8, 0xBE, 0x7C, + 0x4D, 0x4C, 0x13, 0xE3, 0xE4, 0xC2, 0x09, 0x95, 0xA8, 0x4B }; + +// Official CD "Signing Key 004" +// +// -----BEGIN CERTIFICATE----- +// MIICBjCCAa2gAwIBAgIHY3NhY2RrNDAKBggqhkjOPQQDAjBSMQwwCgYDVQQKDAND +// U0ExLDAqBgNVBAMMI01hdHRlciBDZXJ0aWZpY2F0aW9uIGFuZCBUZXN0aW5nIENB +// MRQwEgYKKwYBBAGConwCAQwEQzVBMDAgFw0yMjEwMDMxOTQzMjFaGA8yMDcyMDky +// MDE5NDMyMVowWDEMMAoGA1UECgwDQ1NBMTIwMAYDVQQDDClDZXJ0aWZpY2F0aW9u +// IERlY2xhcmF0aW9uIFNpZ25pbmcgS2V5IDAwNDEUMBIGCisGAQQBgqJ8AgEMBEM1 +// QTAwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAR8/I2IEKic9PoZF3jyr+x4+FF6 +// l6Plf8ITutiI42EedP+2hL3rqKaLJSNKXDWPNzurm20wThMG3XYgpSjRFhwLo2Yw +// ZDASBgNVHRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQU +// 9oYDo2kumBByQZ6h4as4VL13ldMwHwYDVR0jBBgwFoAUl+Rp0MUEFMJvxwH3fpR3 +// OQmN9qUwCgYIKoZIzj0EAwIDRwAwRAIgLqAfkbtLYYdmQsnbn0CWv3G1/lbE36nz +// HbLbW5t6PY4CIE8oyIHsVhNSTPcb3mwRp+Vxhs8tKhbAdwv5BGgDaAHj +// -----END CERTIFICATE----- +// +constexpr uint8_t gCdSigningKey004PubkeyBytes[65] = { + 0x04, 0x7c, 0xfc, 0x8d, 0x88, 0x10, 0xa8, 0x9c, 0xf4, 0xfa, 0x19, 0x17, 0x78, 0xf2, 0xaf, 0xec, 0x78, + 0xf8, 0x51, 0x7a, 0x97, 0xa3, 0xe5, 0x7f, 0xc2, 0x13, 0xba, 0xd8, 0x88, 0xe3, 0x61, 0x1e, 0x74, 0xff, + 0xb6, 0x84, 0xbd, 0xeb, 0xa8, 0xa6, 0x8b, 0x25, 0x23, 0x4a, 0x5c, 0x35, 0x8f, 0x37, 0x3b, 0xab, 0x9b, + 0x6d, 0x30, 0x4e, 0x13, 0x06, 0xdd, 0x76, 0x20, 0xa5, 0x28, 0xd1, 0x16, 0x1c, 0x0b +}; + +constexpr uint8_t gCdSigningKey004Kid[20] = { 0xF6, 0x86, 0x03, 0xA3, 0x69, 0x2E, 0x98, 0x10, 0x72, 0x41, + 0x9E, 0xA1, 0xE1, 0xAB, 0x38, 0x54, 0xBD, 0x77, 0x95, 0xD3 }; + +// Official CD "Signing Key 005" +// +// -----BEGIN CERTIFICATE----- +// MIICBzCCAa2gAwIBAgIHY3NhY2RrNTAKBggqhkjOPQQDAjBSMQwwCgYDVQQKDAND +// U0ExLDAqBgNVBAMMI01hdHRlciBDZXJ0aWZpY2F0aW9uIGFuZCBUZXN0aW5nIENB +// MRQwEgYKKwYBBAGConwCAQwEQzVBMDAgFw0yMjEwMDMxOTQ3MTVaGA8yMDcyMDky +// MDE5NDcxNVowWDEMMAoGA1UECgwDQ1NBMTIwMAYDVQQDDClDZXJ0aWZpY2F0aW9u +// IERlY2xhcmF0aW9uIFNpZ25pbmcgS2V5IDAwNTEUMBIGCisGAQQBgqJ8AgEMBEM1 +// QTAwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARDilLGYqKm1yZH+V63UxNu5K4P +// 2zqpwWkxQms9CGf5EDrn16G4h+n4E6byb3a7zak1k3h8EneMqPKXXcRaIEL5o2Yw +// ZDASBgNVHRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQU +// Y38mNK1i6v5q9mLvuW9v0vy//C8wHwYDVR0jBBgwFoAUl+Rp0MUEFMJvxwH3fpR3 +// OQmN9qUwCgYIKoZIzj0EAwIDSAAwRQIhAM1HQpvkHKxLJByWaSYAPRZgh3Bis18W +// AViq7c/mtzEAAiBZO0lVe6Qo9iQPIBWZaVx/S/YSNO9uKNa/pvFu3V+nIg== +// -----END CERTIFICATE----- +// +constexpr uint8_t gCdSigningKey005PubkeyBytes[65] = { + 0x04, 0x43, 0x8a, 0x52, 0xc6, 0x62, 0xa2, 0xa6, 0xd7, 0x26, 0x47, 0xf9, 0x5e, 0xb7, 0x53, 0x13, 0x6e, + 0xe4, 0xae, 0x0f, 0xdb, 0x3a, 0xa9, 0xc1, 0x69, 0x31, 0x42, 0x6b, 0x3d, 0x08, 0x67, 0xf9, 0x10, 0x3a, + 0xe7, 0xd7, 0xa1, 0xb8, 0x87, 0xe9, 0xf8, 0x13, 0xa6, 0xf2, 0x6f, 0x76, 0xbb, 0xcd, 0xa9, 0x35, 0x93, + 0x78, 0x7c, 0x12, 0x77, 0x8c, 0xa8, 0xf2, 0x97, 0x5d, 0xc4, 0x5a, 0x20, 0x42, 0xf9 +}; + +constexpr uint8_t gCdSigningKey005Kid[20] = { 0x63, 0x7F, 0x26, 0x34, 0xAD, 0x62, 0xEA, 0xFE, 0x6A, 0xF6, + 0x62, 0xEF, 0xB9, 0x6F, 0x6F, 0xD2, 0xFC, 0xBF, 0xFC, 0x2F }; + +struct MatterCDSigningKey +{ + const CertificateKeyId mKid; + const P256PublicKeySpan mPubkey; +}; + +std::array gCdSigningKeys = { { + { FixedByteSpan<20>{ gTestCdPubkeyKid }, FixedByteSpan<65>{ gTestCdPubkeyBytes } }, + { FixedByteSpan<20>{ gCdSigningKey001Kid }, FixedByteSpan<65>{ gCdSigningKey001PubkeyBytes } }, + { FixedByteSpan<20>{ gCdSigningKey002Kid }, FixedByteSpan<65>{ gCdSigningKey002PubkeyBytes } }, + { FixedByteSpan<20>{ gCdSigningKey003Kid }, FixedByteSpan<65>{ gCdSigningKey003PubkeyBytes } }, + { FixedByteSpan<20>{ gCdSigningKey004Kid }, FixedByteSpan<65>{ gCdSigningKey004PubkeyBytes } }, + { FixedByteSpan<20>{ gCdSigningKey005Kid }, FixedByteSpan<65>{ gCdSigningKey005PubkeyBytes } }, +} }; const ArrayAttestationTrustStore kTestAttestationTrustStore{ &kTestPaaRoots[0], ArraySize(kTestPaaRoots) }; @@ -530,11 +645,11 @@ CHIP_ERROR CsaCdKeysTrustStore::AddTrustedKey(const ByteSpan & derCertBytes) CHIP_ERROR CsaCdKeysTrustStore::LookupVerifyingKey(const ByteSpan & kid, Crypto::P256PublicKey & outPubKey) const { // First, search for the well known keys - for (size_t keyIdx = 0; keyIdx < gCdKids.size(); keyIdx++) + for (size_t keyIdx = 0; keyIdx < gCdSigningKeys.size(); keyIdx++) { - if (kid.data_equal(gCdKids[keyIdx])) + if (kid.data_equal(gCdSigningKeys[keyIdx].mKid)) { - outPubKey = gCdPubkeys[keyIdx]; + outPubKey = gCdSigningKeys[keyIdx].mPubkey; return CHIP_NO_ERROR; } } diff --git a/src/credentials/examples/DeviceAttestationCredsExample.cpp b/src/credentials/examples/DeviceAttestationCredsExample.cpp index fa1213ef294b2a..bd09e11df67623 100644 --- a/src/credentials/examples/DeviceAttestationCredsExample.cpp +++ b/src/credentials/examples/DeviceAttestationCredsExample.cpp @@ -72,16 +72,16 @@ CHIP_ERROR ExampleDACProvider::GetCertificationDeclaration(MutableByteSpan & out // 0x8048, 0x8049, 0x804A, 0x804B, 0x804C, 0x804D, 0x804E, 0x804F, 0x8050, 0x8051, 0x8052, 0x8053, 0x8054, 0x8055, 0x8056, // 0x8057, 0x8058, 0x8059, 0x805A, 0x805B, 0x805C, 0x805D, 0x805E, 0x805F, 0x8060, 0x8061, 0x8062, 0x8063 ] //-> device_type_id = 0x0016 - //-> certificate_id = "CSA00000MAT00000-00" + //-> certificate_id = "CSA00000SWC00000-00" //-> security_level = 0 //-> security_information = 0 //-> version_number = 1 //-> certification_type = 0 //-> dac_origin_vendor_id is not present //-> dac_origin_product_id is not present - const uint8_t kCdForAllExamples[540] = { - 0x30, 0x82, 0x02, 0x18, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x82, 0x02, 0x09, 0x30, - 0x82, 0x02, 0x05, 0x02, 0x01, 0x03, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, + const uint8_t kCdForAllExamples[539] = { + 0x30, 0x82, 0x02, 0x17, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x82, 0x02, 0x08, 0x30, + 0x82, 0x02, 0x04, 0x02, 0x01, 0x03, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x30, 0x82, 0x01, 0x70, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, 0x01, 0x61, 0x04, 0x82, 0x01, 0x5d, 0x15, 0x24, 0x00, 0x01, 0x25, 0x01, 0xf1, 0xff, 0x36, 0x02, 0x05, 0x00, 0x80, 0x05, 0x01, 0x80, 0x05, 0x02, 0x80, 0x05, 0x03, 0x80, 0x05, 0x04, 0x80, 0x05, 0x05, 0x80, 0x05, 0x06, 0x80, 0x05, 0x07, 0x80, 0x05, 0x08, @@ -99,14 +99,14 @@ CHIP_ERROR ExampleDACProvider::GetCertificationDeclaration(MutableByteSpan & out 0x05, 0x52, 0x80, 0x05, 0x53, 0x80, 0x05, 0x54, 0x80, 0x05, 0x55, 0x80, 0x05, 0x56, 0x80, 0x05, 0x57, 0x80, 0x05, 0x58, 0x80, 0x05, 0x59, 0x80, 0x05, 0x5a, 0x80, 0x05, 0x5b, 0x80, 0x05, 0x5c, 0x80, 0x05, 0x5d, 0x80, 0x05, 0x5e, 0x80, 0x05, 0x5f, 0x80, 0x05, 0x60, 0x80, 0x05, 0x61, 0x80, 0x05, 0x62, 0x80, 0x05, 0x63, 0x80, 0x18, 0x24, 0x03, 0x16, 0x2c, 0x04, - 0x13, 0x43, 0x53, 0x41, 0x30, 0x30, 0x30, 0x30, 0x30, 0x4d, 0x41, 0x54, 0x30, 0x30, 0x30, 0x30, 0x30, 0x2d, 0x30, 0x30, - 0x24, 0x05, 0x00, 0x24, 0x06, 0x00, 0x24, 0x07, 0x01, 0x24, 0x08, 0x00, 0x18, 0x31, 0x7d, 0x30, 0x7b, 0x02, 0x01, 0x03, - 0x80, 0x14, 0x83, 0xfa, 0xd7, 0x81, 0xe8, 0x2d, 0x01, 0x8b, 0x4f, 0x14, 0xf0, 0xa1, 0xc7, 0xf6, 0x84, 0x01, 0x8c, 0xc5, - 0xd1, 0x9f, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x30, 0x0a, 0x06, 0x08, 0x2a, - 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x04, 0x47, 0x30, 0x45, 0x02, 0x20, 0x57, 0xc4, 0xb8, 0x18, 0x3a, 0x93, 0xa6, - 0xb8, 0xc3, 0x60, 0x3e, 0x77, 0xde, 0x8e, 0xb1, 0x94, 0x8c, 0x9c, 0xc0, 0x50, 0x60, 0xa6, 0x1a, 0xa9, 0xd7, 0x43, 0xeb, - 0xea, 0xf9, 0x5f, 0x73, 0xc9, 0x02, 0x21, 0x00, 0xa3, 0xd5, 0xa1, 0x1f, 0xb0, 0x71, 0xf2, 0x13, 0xa5, 0xe1, 0x24, 0xed, - 0xe7, 0xe1, 0xee, 0x16, 0x7e, 0x19, 0xc2, 0x8c, 0x3d, 0xed, 0x98, 0x4c, 0xf1, 0x03, 0x96, 0x48, 0xe8, 0x8c, 0xd8, 0x06 + 0x13, 0x43, 0x53, 0x41, 0x30, 0x30, 0x30, 0x30, 0x30, 0x53, 0x57, 0x43, 0x30, 0x30, 0x30, 0x30, 0x30, 0x2d, 0x30, 0x30, + 0x24, 0x05, 0x00, 0x24, 0x06, 0x00, 0x24, 0x07, 0x01, 0x24, 0x08, 0x00, 0x18, 0x31, 0x7c, 0x30, 0x7a, 0x02, 0x01, 0x03, + 0x80, 0x14, 0xfe, 0x34, 0x3f, 0x95, 0x99, 0x47, 0x76, 0x3b, 0x61, 0xee, 0x45, 0x39, 0x13, 0x13, 0x38, 0x49, 0x4f, 0xe6, + 0x7d, 0x8e, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x30, 0x0a, 0x06, 0x08, 0x2a, + 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x04, 0x46, 0x30, 0x44, 0x02, 0x20, 0x4a, 0x12, 0xf8, 0xd4, 0x2f, 0x90, 0x23, + 0x5c, 0x05, 0xa7, 0x71, 0x21, 0xcb, 0xeb, 0xae, 0x15, 0xd5, 0x90, 0x14, 0x65, 0x58, 0xe9, 0xc9, 0xb4, 0x7a, 0x1a, 0x38, + 0xf7, 0xa3, 0x6a, 0x7d, 0xc5, 0x02, 0x20, 0x20, 0xa4, 0x74, 0x28, 0x97, 0xc3, 0x0a, 0xed, 0xa0, 0xa5, 0x6b, 0x36, 0xe1, + 0x4e, 0xbb, 0xc8, 0x5b, 0xbd, 0xb7, 0x44, 0x93, 0xf9, 0x93, 0x58, 0x1e, 0xb0, 0x44, 0x4e, 0xd6, 0xca, 0x94, 0x0b }; return CopySpanToMutableSpan(ByteSpan{ kCdForAllExamples }, out_cd_buffer); } From 9945f23da62b9d8c657dd89fb3b81aa62a90f327 Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Wed, 5 Oct 2022 13:15:13 -0400 Subject: [PATCH 12/13] Update more data types to match spec (#23023) --- scripts/idl/generators/types.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/scripts/idl/generators/types.py b/scripts/idl/generators/types.py index e96e852dac6b96..b6f216802de0d8 100644 --- a/scripts/idl/generators/types.py +++ b/scripts/idl/generators/types.py @@ -162,7 +162,7 @@ def is_struct(self) -> bool: return self.item_type == IdlItemType.STRUCT -# Data types, held by ZAP in chip-types.xml +# Data types, held by ZAP in chip-types.xml and generally by the spec. __CHIP_SIZED_TYPES__ = { "bitmap16": BasicInteger(idl_name="bitmap16", byte_count=2, is_signed=False), "bitmap24": BasicInteger(idl_name="bitmap24", byte_count=3, is_signed=False), @@ -189,7 +189,7 @@ def is_struct(self) -> bool: "int8s": BasicInteger(idl_name="int8s", byte_count=1, is_signed=True), "int8u": BasicInteger(idl_name="int8u", byte_count=1, is_signed=False), # Derived types - # Size and signdness should generally follow DataModelTypes.h or basic-types.h + # Specification describes them in section '7.18.2. Derived Data Types' "action_id": BasicInteger(idl_name="action_id", byte_count=1, is_signed=False), "attrib_id": BasicInteger(idl_name="attrib_id", byte_count=4, is_signed=False), "cluster_id": BasicInteger(idl_name="cluster_id", byte_count=4, is_signed=False), @@ -210,10 +210,9 @@ def is_struct(self) -> bool: "percent": BasicInteger(idl_name="percent", byte_count=1, is_signed=False), "percent100ths": BasicInteger(idl_name="percent100ths", byte_count=2, is_signed=False), "status": BasicInteger(idl_name="status", byte_count=2, is_signed=False), - "systime_us": BasicInteger(idl_name="systime_us", byte_count=8, is_signed=True), - "tod": BasicInteger(idl_name="tod", byte_count=4, is_signed=True), - "trans_id": BasicInteger(idl_name="trans_id", byte_count=4, is_signed=True), - "utc": BasicInteger(idl_name="utc", byte_count=4, is_signed=False), + "systime_us": BasicInteger(idl_name="systime_us", byte_count=8, is_signed=False), + "tod": BasicInteger(idl_name="tod", byte_count=4, is_signed=False), + "trans_id": BasicInteger(idl_name="trans_id", byte_count=4, is_signed=False), "vendor_id": BasicInteger(idl_name="vendor_id", byte_count=2, is_signed=False), } From c6025f85c884dadc3c9c6c32350d4216e55d7e80 Mon Sep 17 00:00:00 2001 From: andrei-menzopol <96489227+andrei-menzopol@users.noreply.github.com> Date: Wed, 5 Oct 2022 20:20:38 +0300 Subject: [PATCH 13/13] Add contact-sensor-app (#22966) * [K32W0] Add contact-sensor-app * Add K32W0 contact-sensor-app * Add contact-sensor-app-common files * Generate zap-files Signed-off-by: Ethan Tan Signed-off-by: Andrei Menzopol * Restyled by whitespace * Restyled by clang-format * Restyled by gn * Restyled by prettier-markdown * Fix zap file & misspell Signed-off-by: Andrei Menzopol * Update matter, zap files and regenerate contact-sensor-app/zap-generated Signed-off-by: Andrei Menzopol * Add contact-sensor build changes Signed-off-by: Andrei Menzopol * Update contact-sensor-app matter file Signed-off-by: Andrei Menzopol Signed-off-by: Ethan Tan Signed-off-by: Andrei Menzopol Co-authored-by: Restyled.io --- .github/workflows/examples-k32w.yaml | 8 + config/k32w/toolchain/BUILD.gn | 7 + .../contact-sensor-common/BUILD.gn | 25 + .../contact-sensor-app.matter | 1570 +++ .../contact-sensor-app.zap | 8687 +++++++++++++++++ .../contact-sensor-app/nxp/k32w/k32w0/.gn | 28 + .../nxp/k32w/k32w0/BUILD.gn | 143 + .../nxp/k32w/k32w0/README.md | 592 ++ .../nxp/k32w/k32w0/args.gni | 23 + .../nxp/k32w/k32w0/build_overrides | 1 + .../k32w/k32w0/include/CHIPProjectConfig.h | 231 + .../nxp/k32w/k32w0/include/FreeRTOSConfig.h | 187 + .../nxp/k32w/k32w0/main/AppTask.cpp | 888 ++ .../k32w/k32w0/main/ContactSensorManager.cpp | 83 + .../nxp/k32w/k32w0/main/ZclCallbacks.cpp | 96 + .../nxp/k32w/k32w0/main/include/AppEvent.h | 62 + .../nxp/k32w/k32w0/main/include/AppTask.h | 131 + .../k32w0/main/include/ContactSensorManager.h | 65 + .../nxp/k32w/k32w0/main/include/app_config.h | 56 + .../nxp/k32w/k32w0/main/main.cpp | 201 + .../k32w/k32w0/third_party/connectedhomeip | 1 + scripts/build/build/targets.py | 3 + scripts/build/builders/k32w.py | 3 + .../testdata/all_targets_except_host.txt | 2 + .../build/testdata/build_all_except_host.txt | 16 + .../glob_star_targets_except_host.txt | 1 + .../zap-generated/CHIPClientCallbacks.h | 32 + .../zap-generated/CHIPClusters.h | 44 + .../zap-generated/IMClusterCommandHandler.cpp | 857 ++ .../PluginApplicationCallbacks.h | 48 + .../contact-sensor-app/zap-generated/access.h | 266 + .../zap-generated/af-gen-event.h | 0 .../zap-generated/callback-stub.cpp | 319 + .../zap-generated/endpoint_config.h | 964 ++ .../zap-generated/gen_config.h | 176 + .../zap-generated/gen_tokens.h | 45 + 36 files changed, 15861 insertions(+) create mode 100755 examples/contact-sensor-app/contact-sensor-common/BUILD.gn create mode 100644 examples/contact-sensor-app/contact-sensor-common/contact-sensor-app.matter create mode 100644 examples/contact-sensor-app/contact-sensor-common/contact-sensor-app.zap create mode 100644 examples/contact-sensor-app/nxp/k32w/k32w0/.gn create mode 100644 examples/contact-sensor-app/nxp/k32w/k32w0/BUILD.gn create mode 100644 examples/contact-sensor-app/nxp/k32w/k32w0/README.md create mode 100644 examples/contact-sensor-app/nxp/k32w/k32w0/args.gni create mode 120000 examples/contact-sensor-app/nxp/k32w/k32w0/build_overrides create mode 100644 examples/contact-sensor-app/nxp/k32w/k32w0/include/CHIPProjectConfig.h create mode 100644 examples/contact-sensor-app/nxp/k32w/k32w0/include/FreeRTOSConfig.h create mode 100644 examples/contact-sensor-app/nxp/k32w/k32w0/main/AppTask.cpp create mode 100644 examples/contact-sensor-app/nxp/k32w/k32w0/main/ContactSensorManager.cpp create mode 100644 examples/contact-sensor-app/nxp/k32w/k32w0/main/ZclCallbacks.cpp create mode 100644 examples/contact-sensor-app/nxp/k32w/k32w0/main/include/AppEvent.h create mode 100644 examples/contact-sensor-app/nxp/k32w/k32w0/main/include/AppTask.h create mode 100644 examples/contact-sensor-app/nxp/k32w/k32w0/main/include/ContactSensorManager.h create mode 100644 examples/contact-sensor-app/nxp/k32w/k32w0/main/include/app_config.h create mode 100644 examples/contact-sensor-app/nxp/k32w/k32w0/main/main.cpp create mode 120000 examples/contact-sensor-app/nxp/k32w/k32w0/third_party/connectedhomeip create mode 100644 zzz_generated/contact-sensor-app/zap-generated/CHIPClientCallbacks.h create mode 100644 zzz_generated/contact-sensor-app/zap-generated/CHIPClusters.h create mode 100644 zzz_generated/contact-sensor-app/zap-generated/IMClusterCommandHandler.cpp create mode 100644 zzz_generated/contact-sensor-app/zap-generated/PluginApplicationCallbacks.h create mode 100644 zzz_generated/contact-sensor-app/zap-generated/access.h create mode 100755 zzz_generated/contact-sensor-app/zap-generated/af-gen-event.h create mode 100644 zzz_generated/contact-sensor-app/zap-generated/callback-stub.cpp create mode 100644 zzz_generated/contact-sensor-app/zap-generated/endpoint_config.h create mode 100644 zzz_generated/contact-sensor-app/zap-generated/gen_config.h create mode 100644 zzz_generated/contact-sensor-app/zap-generated/gen_tokens.h diff --git a/.github/workflows/examples-k32w.yaml b/.github/workflows/examples-k32w.yaml index ffdfe159633598..696c2c6e04fea6 100644 --- a/.github/workflows/examples-k32w.yaml +++ b/.github/workflows/examples-k32w.yaml @@ -74,6 +74,7 @@ jobs: --target k32w-light-ota-se \ --target k32w-light-release-no-ota \ --target k32w-lock-low-power-release \ + --target k32w-contact-low-power-release \ --target k32w-shell-release \ build \ --copy-artifacts-to out/artifacts \ @@ -92,6 +93,13 @@ jobs: k32w k32w0+release lock \ out/artifacts/k32w-lock-low-power-release/chip-k32w0x-lock-example \ /tmp/bloat_reports/ + - name: Get contact size stats + timeout-minutes: 5 + run: | + .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ + k32w k32w0+release contact \ + out/artifacts/k32w-contact-low-power-release/chip-k32w0x-contact-example \ + /tmp/bloat_reports/ - name: Uploading Size Reports uses: actions/upload-artifact@v2 if: ${{ !env.ACT }} diff --git a/config/k32w/toolchain/BUILD.gn b/config/k32w/toolchain/BUILD.gn index 6faaab239872cf..f386bcd0cd4c97 100644 --- a/config/k32w/toolchain/BUILD.gn +++ b/config/k32w/toolchain/BUILD.gn @@ -31,6 +31,13 @@ arm_toolchain("k32w_lock_app") { } } +arm_toolchain("k32w_contact_sensor_app") { + toolchain_args = { + current_os = "freertos" + import("${chip_root}/examples/contact-sensor-app/nxp/k32w/k32w0/args.gni") + } +} + arm_toolchain("k32w_shell_app") { toolchain_args = { current_os = "freertos" diff --git a/examples/contact-sensor-app/contact-sensor-common/BUILD.gn b/examples/contact-sensor-app/contact-sensor-common/BUILD.gn new file mode 100755 index 00000000000000..ddae4d2d0defc5 --- /dev/null +++ b/examples/contact-sensor-app/contact-sensor-common/BUILD.gn @@ -0,0 +1,25 @@ +# Copyright (c) 2020 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. + +import("//build_overrides/chip.gni") +import("${chip_root}/examples/common/pigweed/pigweed_rpcs.gni") +import("${chip_root}/src/app/chip_data_model.gni") + +chip_data_model("contact-sensor-common") { + zap_file = "contact-sensor-app.zap" + + zap_pregenerated_dir = + "${chip_root}/zzz_generated/contact-sensor-app/zap-generated" + is_server = true +} diff --git a/examples/contact-sensor-app/contact-sensor-common/contact-sensor-app.matter b/examples/contact-sensor-app/contact-sensor-common/contact-sensor-app.matter new file mode 100644 index 00000000000000..5fb1dbfd1cbaaa --- /dev/null +++ b/examples/contact-sensor-app/contact-sensor-common/contact-sensor-app.matter @@ -0,0 +1,1570 @@ +// This IDL was generated automatically by ZAP. +// It is for view/code review purposes only. + +struct LabelStruct { + char_string<16> label = 0; + char_string<16> value = 1; +} + +server cluster Identify = 3 { + enum IdentifyEffectIdentifier : ENUM8 { + kBlink = 0; + kBreathe = 1; + kOkay = 2; + kChannelChange = 11; + kFinishEffect = 254; + kStopEffect = 255; + } + + enum IdentifyEffectVariant : ENUM8 { + kDefault = 0; + } + + enum IdentifyIdentifyType : ENUM8 { + kNone = 0; + kVisibleLight = 1; + kVisibleLED = 2; + kAudibleBeep = 3; + kDisplay = 4; + kActuator = 5; + } + + attribute int16u identifyTime = 0; + readonly attribute enum8 identifyType = 1; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct IdentifyRequest { + INT16U identifyTime = 0; + } + + request struct TriggerEffectRequest { + IdentifyEffectIdentifier effectIdentifier = 0; + IdentifyEffectVariant effectVariant = 1; + } + + command access(invoke: manage) Identify(IdentifyRequest): DefaultSuccess = 0; + command access(invoke: manage) TriggerEffect(TriggerEffectRequest): DefaultSuccess = 64; +} + +server cluster Groups = 4 { + bitmap GroupClusterFeature : BITMAP32 { + kGroupNames = 0x1; + } + + readonly attribute bitmap8 nameSupport = 0; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct AddGroupRequest { + group_id groupId = 0; + CHAR_STRING groupName = 1; + } + + request struct ViewGroupRequest { + group_id groupId = 0; + } + + request struct GetGroupMembershipRequest { + group_id groupList[] = 0; + } + + request struct RemoveGroupRequest { + group_id groupId = 0; + } + + request struct AddGroupIfIdentifyingRequest { + group_id groupId = 0; + CHAR_STRING groupName = 1; + } + + response struct AddGroupResponse = 0 { + ENUM8 status = 0; + group_id groupId = 1; + } + + response struct ViewGroupResponse = 1 { + ENUM8 status = 0; + group_id groupId = 1; + CHAR_STRING groupName = 2; + } + + response struct GetGroupMembershipResponse = 2 { + nullable INT8U capacity = 0; + group_id groupList[] = 1; + } + + response struct RemoveGroupResponse = 3 { + ENUM8 status = 0; + group_id groupId = 1; + } + + fabric command access(invoke: manage) AddGroup(AddGroupRequest): AddGroupResponse = 0; + fabric command ViewGroup(ViewGroupRequest): ViewGroupResponse = 1; + fabric command GetGroupMembership(GetGroupMembershipRequest): GetGroupMembershipResponse = 2; + fabric command access(invoke: manage) RemoveGroup(RemoveGroupRequest): RemoveGroupResponse = 3; + fabric command access(invoke: manage) RemoveAllGroups(): DefaultSuccess = 4; + fabric command access(invoke: manage) AddGroupIfIdentifying(AddGroupIfIdentifyingRequest): DefaultSuccess = 5; +} + +server cluster Descriptor = 29 { + struct DeviceTypeStruct { + devtype_id type = 0; + int16u revision = 1; + } + + readonly attribute DeviceTypeStruct deviceTypeList[] = 0; + readonly attribute CLUSTER_ID serverList[] = 1; + readonly attribute CLUSTER_ID clientList[] = 2; + readonly attribute ENDPOINT_NO partsList[] = 3; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; +} + +server cluster AccessControl = 31 { + enum AuthMode : ENUM8 { + kPase = 1; + kCase = 2; + kGroup = 3; + } + + enum ChangeTypeEnum : ENUM8 { + kChanged = 0; + kAdded = 1; + kRemoved = 2; + } + + enum Privilege : ENUM8 { + kView = 1; + kProxyView = 2; + kOperate = 3; + kManage = 4; + kAdminister = 5; + } + + fabric_scoped struct AccessControlEntry { + fabric_sensitive Privilege privilege = 1; + fabric_sensitive AuthMode authMode = 2; + nullable fabric_sensitive int64u subjects[] = 3; + nullable fabric_sensitive Target targets[] = 4; + fabric_idx fabricIndex = 254; + } + + struct Target { + nullable cluster_id cluster = 0; + nullable endpoint_no endpoint = 1; + nullable devtype_id deviceType = 2; + } + + fabric_scoped struct ExtensionEntry { + fabric_sensitive octet_string<128> data = 1; + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) AccessControlEntryChanged = 0 { + nullable node_id adminNodeID = 1; + nullable INT16U adminPasscodeID = 2; + ChangeTypeEnum changeType = 3; + nullable AccessControlEntry latestValue = 4; + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) AccessControlExtensionChanged = 1 { + nullable node_id adminNodeID = 1; + nullable INT16U adminPasscodeID = 2; + ChangeTypeEnum changeType = 3; + nullable ExtensionEntry latestValue = 4; + fabric_idx fabricIndex = 254; + } + + attribute access(read: administer, write: administer) AccessControlEntry acl[] = 0; + attribute access(read: administer, write: administer) ExtensionEntry extension[] = 1; + readonly attribute int16u subjectsPerAccessControlEntry = 2; + readonly attribute int16u targetsPerAccessControlEntry = 3; + readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; +} + +server cluster Basic = 40 { + struct CapabilityMinimaStruct { + int16u caseSessionsPerFabric = 0; + int16u subscriptionsPerFabric = 1; + } + + critical event StartUp = 0 { + INT32U softwareVersion = 0; + } + + critical event ShutDown = 1 { + } + + info event Leave = 2 { + fabric_idx fabricIndex = 0; + } + + info event ReachableChanged = 3 { + boolean reachableNewValue = 0; + } + + readonly attribute int16u dataModelRevision = 0; + readonly attribute char_string<32> vendorName = 1; + readonly attribute vendor_id vendorID = 2; + readonly attribute char_string<32> productName = 3; + readonly attribute int16u productID = 4; + attribute access(write: manage) char_string<32> nodeLabel = 5; + attribute access(write: administer) char_string<2> location = 6; + readonly attribute int16u hardwareVersion = 7; + readonly attribute char_string<64> hardwareVersionString = 8; + readonly attribute int32u softwareVersion = 9; + readonly attribute char_string<64> softwareVersionString = 10; + readonly attribute char_string<16> manufacturingDate = 11; + readonly attribute char_string<32> partNumber = 12; + readonly attribute long_char_string<256> productURL = 13; + readonly attribute char_string<64> productLabel = 14; + readonly attribute char_string<32> serialNumber = 15; + attribute access(write: manage) boolean localConfigDisabled = 16; + readonly attribute boolean reachable = 17; + readonly attribute char_string<32> uniqueID = 18; + readonly attribute CapabilityMinimaStruct capabilityMinima = 19; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; +} + +client cluster OtaSoftwareUpdateProvider = 41 { + enum OTAApplyUpdateAction : ENUM8 { + kProceed = 0; + kAwaitNextAction = 1; + kDiscontinue = 2; + } + + enum OTADownloadProtocol : ENUM8 { + kBDXSynchronous = 0; + kBDXAsynchronous = 1; + kHttps = 2; + kVendorSpecific = 3; + } + + enum OTAQueryStatus : ENUM8 { + kUpdateAvailable = 0; + kBusy = 1; + kNotAvailable = 2; + kDownloadProtocolNotSupported = 3; + } + + readonly attribute int16u clusterRevision = 65533; + + request struct QueryImageRequest { + vendor_id vendorId = 0; + INT16U productId = 1; + INT32U softwareVersion = 2; + OTADownloadProtocol protocolsSupported[] = 3; + optional INT16U hardwareVersion = 4; + optional CHAR_STRING<2> location = 5; + optional BOOLEAN requestorCanConsent = 6; + optional OCTET_STRING<512> metadataForProvider = 7; + } + + request struct ApplyUpdateRequestRequest { + OCTET_STRING<32> updateToken = 0; + INT32U newVersion = 1; + } + + request struct NotifyUpdateAppliedRequest { + OCTET_STRING<32> updateToken = 0; + INT32U softwareVersion = 1; + } + + response struct QueryImageResponse = 1 { + OTAQueryStatus status = 0; + optional INT32U delayedActionTime = 1; + optional CHAR_STRING<256> imageURI = 2; + optional INT32U softwareVersion = 3; + optional CHAR_STRING<64> softwareVersionString = 4; + optional OCTET_STRING<32> updateToken = 5; + optional BOOLEAN userConsentNeeded = 6; + optional OCTET_STRING<512> metadataForRequestor = 7; + } + + response struct ApplyUpdateResponse = 3 { + OTAApplyUpdateAction action = 0; + INT32U delayedActionTime = 1; + } + + command QueryImage(QueryImageRequest): QueryImageResponse = 0; + command ApplyUpdateRequest(ApplyUpdateRequestRequest): ApplyUpdateResponse = 2; + command NotifyUpdateApplied(NotifyUpdateAppliedRequest): DefaultSuccess = 4; +} + +server cluster OtaSoftwareUpdateRequestor = 42 { + enum OTAAnnouncementReason : ENUM8 { + kSimpleAnnouncement = 0; + kUpdateAvailable = 1; + kUrgentUpdateAvailable = 2; + } + + enum OTAChangeReasonEnum : ENUM8 { + kUnknown = 0; + kSuccess = 1; + kFailure = 2; + kTimeOut = 3; + kDelayByProvider = 4; + } + + enum OTAUpdateStateEnum : ENUM8 { + kUnknown = 0; + kIdle = 1; + kQuerying = 2; + kDelayedOnQuery = 3; + kDownloading = 4; + kApplying = 5; + kDelayedOnApply = 6; + kRollingBack = 7; + kDelayedOnUserConsent = 8; + } + + fabric_scoped struct ProviderLocation { + node_id providerNodeID = 1; + endpoint_no endpoint = 2; + fabric_idx fabricIndex = 254; + } + + info event StateTransition = 0 { + OTAUpdateStateEnum previousState = 0; + OTAUpdateStateEnum newState = 1; + OTAChangeReasonEnum reason = 2; + nullable INT32U targetSoftwareVersion = 3; + } + + critical event VersionApplied = 1 { + INT32U softwareVersion = 0; + INT16U productID = 1; + } + + info event DownloadError = 2 { + INT32U softwareVersion = 0; + INT64U bytesDownloaded = 1; + nullable INT8U progressPercent = 2; + nullable INT64S platformCode = 3; + } + + attribute ProviderLocation defaultOtaProviders[] = 0; + readonly attribute boolean updatePossible = 1; + readonly attribute OTAUpdateStateEnum updateState = 2; + readonly attribute nullable int8u updateStateProgress = 3; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct AnnounceOtaProviderRequest { + node_id providerNodeId = 0; + vendor_id vendorId = 1; + OTAAnnouncementReason announcementReason = 2; + optional OCTET_STRING<512> metadataForNode = 3; + endpoint_no endpoint = 4; + } + + command AnnounceOtaProvider(AnnounceOtaProviderRequest): DefaultSuccess = 0; +} + +server cluster LocalizationConfiguration = 43 { + attribute char_string<35> activeLocale = 0; + readonly attribute CHAR_STRING supportedLocales[] = 1; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; +} + +server cluster TimeFormatLocalization = 44 { + enum CalendarType : ENUM8 { + kBuddhist = 0; + kChinese = 1; + kCoptic = 2; + kEthiopian = 3; + kGregorian = 4; + kHebrew = 5; + kIndian = 6; + kIslamic = 7; + kJapanese = 8; + kKorean = 9; + kPersian = 10; + kTaiwanese = 11; + } + + enum HourFormat : ENUM8 { + k12hr = 0; + k24hr = 1; + } + + attribute HourFormat hourFormat = 0; + attribute CalendarType activeCalendarType = 1; + readonly attribute CalendarType supportedCalendarTypes[] = 2; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; +} + +server cluster GeneralCommissioning = 48 { + enum CommissioningError : ENUM8 { + kOk = 0; + kValueOutsideRange = 1; + kInvalidAuthentication = 2; + kNoFailSafe = 3; + kBusyWithOtherAdmin = 4; + } + + enum RegulatoryLocationType : ENUM8 { + kIndoor = 0; + kOutdoor = 1; + kIndoorOutdoor = 2; + } + + struct BasicCommissioningInfo { + int16u failSafeExpiryLengthSeconds = 0; + int16u maxCumulativeFailsafeSeconds = 1; + } + + attribute access(write: administer) int64u breadcrumb = 0; + readonly attribute BasicCommissioningInfo basicCommissioningInfo = 1; + readonly attribute RegulatoryLocationType regulatoryConfig = 2; + readonly attribute RegulatoryLocationType locationCapability = 3; + readonly attribute boolean supportsConcurrentConnection = 4; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct ArmFailSafeRequest { + INT16U expiryLengthSeconds = 0; + INT64U breadcrumb = 1; + } + + request struct SetRegulatoryConfigRequest { + RegulatoryLocationType newRegulatoryConfig = 0; + CHAR_STRING countryCode = 1; + INT64U breadcrumb = 2; + } + + response struct ArmFailSafeResponse = 1 { + CommissioningError errorCode = 0; + CHAR_STRING debugText = 1; + } + + response struct SetRegulatoryConfigResponse = 3 { + CommissioningError errorCode = 0; + CHAR_STRING debugText = 1; + } + + response struct CommissioningCompleteResponse = 5 { + CommissioningError errorCode = 0; + CHAR_STRING debugText = 1; + } + + command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; + command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; + fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; +} + +server cluster NetworkCommissioning = 49 { + enum NetworkCommissioningStatus : ENUM8 { + kSuccess = 0; + kOutOfRange = 1; + kBoundsExceeded = 2; + kNetworkIDNotFound = 3; + kDuplicateNetworkID = 4; + kNetworkNotFound = 5; + kRegulatoryError = 6; + kAuthFailure = 7; + kUnsupportedSecurity = 8; + kOtherConnectionFailure = 9; + kIPV6Failed = 10; + kIPBindFailed = 11; + kUnknownError = 12; + } + + enum WiFiBand : ENUM8 { + k2g4 = 0; + k3g65 = 1; + k5g = 2; + k6g = 3; + k60g = 4; + } + + bitmap NetworkCommissioningFeature : BITMAP32 { + kWiFiNetworkInterface = 0x1; + kThreadNetworkInterface = 0x2; + kEthernetNetworkInterface = 0x4; + } + + bitmap WiFiSecurity : BITMAP8 { + kUnencrypted = 0x1; + kWepPersonal = 0x2; + kWpaPersonal = 0x4; + kWpa2Personal = 0x8; + kWpa3Personal = 0x10; + } + + struct NetworkInfo { + octet_string<32> networkID = 0; + boolean connected = 1; + } + + struct WiFiInterfaceScanResult { + WiFiSecurity security = 0; + octet_string<32> ssid = 1; + octet_string<6> bssid = 2; + int16u channel = 3; + WiFiBand wiFiBand = 4; + int8s rssi = 5; + } + + struct ThreadInterfaceScanResult { + int16u panId = 0; + int64u extendedPanId = 1; + char_string<16> networkName = 2; + int16u channel = 3; + int8u version = 4; + octet_string<8> extendedAddress = 5; + int8s rssi = 6; + int8u lqi = 7; + } + + readonly attribute access(read: administer) int8u maxNetworks = 0; + readonly attribute access(read: administer) NetworkInfo networks[] = 1; + readonly attribute int8u scanMaxTimeSeconds = 2; + readonly attribute int8u connectMaxTimeSeconds = 3; + attribute access(write: administer) boolean interfaceEnabled = 4; + readonly attribute access(read: administer) nullable NetworkCommissioningStatus lastNetworkingStatus = 5; + readonly attribute access(read: administer) nullable octet_string<32> lastNetworkID = 6; + readonly attribute access(read: administer) nullable int32s lastConnectErrorValue = 7; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct ScanNetworksRequest { + optional nullable OCTET_STRING<32> ssid = 0; + optional INT64U breadcrumb = 1; + } + + request struct AddOrUpdateWiFiNetworkRequest { + OCTET_STRING<32> ssid = 0; + OCTET_STRING<64> credentials = 1; + optional INT64U breadcrumb = 2; + } + + request struct AddOrUpdateThreadNetworkRequest { + OCTET_STRING<254> operationalDataset = 0; + optional INT64U breadcrumb = 1; + } + + request struct RemoveNetworkRequest { + OCTET_STRING<32> networkID = 0; + optional INT64U breadcrumb = 1; + } + + request struct ConnectNetworkRequest { + OCTET_STRING<32> networkID = 0; + optional INT64U breadcrumb = 1; + } + + request struct ReorderNetworkRequest { + OCTET_STRING<32> networkID = 0; + INT8U networkIndex = 1; + optional INT64U breadcrumb = 2; + } + + response struct ScanNetworksResponse = 1 { + NetworkCommissioningStatus networkingStatus = 0; + optional CHAR_STRING debugText = 1; + optional WiFiInterfaceScanResult wiFiScanResults[] = 2; + optional ThreadInterfaceScanResult threadScanResults[] = 3; + } + + response struct NetworkConfigResponse = 5 { + NetworkCommissioningStatus networkingStatus = 0; + optional CHAR_STRING<512> debugText = 1; + optional INT8U networkIndex = 2; + } + + response struct ConnectNetworkResponse = 7 { + NetworkCommissioningStatus networkingStatus = 0; + optional CHAR_STRING debugText = 1; + nullable INT32S errorValue = 2; + } + + command access(invoke: administer) ScanNetworks(ScanNetworksRequest): ScanNetworksResponse = 0; + command access(invoke: administer) AddOrUpdateWiFiNetwork(AddOrUpdateWiFiNetworkRequest): NetworkConfigResponse = 2; + command access(invoke: administer) AddOrUpdateThreadNetwork(AddOrUpdateThreadNetworkRequest): NetworkConfigResponse = 3; + command access(invoke: administer) RemoveNetwork(RemoveNetworkRequest): NetworkConfigResponse = 4; + command access(invoke: administer) ConnectNetwork(ConnectNetworkRequest): ConnectNetworkResponse = 6; + command access(invoke: administer) ReorderNetwork(ReorderNetworkRequest): NetworkConfigResponse = 8; +} + +server cluster DiagnosticLogs = 50 { + enum LogsIntent : ENUM8 { + kEndUserSupport = 0; + kNetworkDiag = 1; + kCrashLogs = 2; + } + + enum LogsStatus : ENUM8 { + kSuccess = 0; + kExhausted = 1; + kNoLogs = 2; + kBusy = 3; + kDenied = 4; + } + + enum LogsTransferProtocol : ENUM8 { + kResponsePayload = 0; + kBdx = 1; + } + + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct RetrieveLogsRequestRequest { + LogsIntent intent = 0; + LogsTransferProtocol requestedProtocol = 1; + OCTET_STRING<32> transferFileDesignator = 2; + } + + command RetrieveLogsRequest(RetrieveLogsRequestRequest): RetrieveLogsResponse = 0; +} + +server cluster GeneralDiagnostics = 51 { + enum BootReasonType : ENUM8 { + kUnspecified = 0; + kPowerOnReboot = 1; + kBrownOutReset = 2; + kSoftwareWatchdogReset = 3; + kHardwareWatchdogReset = 4; + kSoftwareUpdateCompleted = 5; + kSoftwareReset = 6; + } + + enum HardwareFaultType : ENUM8 { + kUnspecified = 0; + kRadio = 1; + kSensor = 2; + kResettableOverTemp = 3; + kNonResettableOverTemp = 4; + kPowerSource = 5; + kVisualDisplayFault = 6; + kAudioOutputFault = 7; + kUserInterfaceFault = 8; + kNonVolatileMemoryError = 9; + kTamperDetected = 10; + } + + enum InterfaceType : ENUM8 { + kUnspecified = 0; + kWiFi = 1; + kEthernet = 2; + kCellular = 3; + kThread = 4; + } + + enum NetworkFaultType : ENUM8 { + kUnspecified = 0; + kHardwareFailure = 1; + kNetworkJammed = 2; + kConnectionFailed = 3; + } + + enum RadioFaultType : ENUM8 { + kUnspecified = 0; + kWiFiFault = 1; + kCellularFault = 2; + kThreadFault = 3; + kNFCFault = 4; + kBLEFault = 5; + kEthernetFault = 6; + } + + struct NetworkInterfaceType { + char_string<32> name = 0; + boolean isOperational = 1; + nullable boolean offPremiseServicesReachableIPv4 = 2; + nullable boolean offPremiseServicesReachableIPv6 = 3; + octet_string<8> hardwareAddress = 4; + octet_string IPv4Addresses[] = 5; + octet_string IPv6Addresses[] = 6; + InterfaceType type = 7; + } + + critical event HardwareFaultChange = 0 { + HardwareFaultType current[] = 0; + HardwareFaultType previous[] = 1; + } + + critical event RadioFaultChange = 1 { + RadioFaultType current[] = 0; + RadioFaultType previous[] = 1; + } + + critical event NetworkFaultChange = 2 { + NetworkFaultType current[] = 0; + NetworkFaultType previous[] = 1; + } + + critical event BootReason = 3 { + BootReasonType bootReason = 0; + } + + readonly attribute NetworkInterfaceType networkInterfaces[] = 0; + readonly attribute int16u rebootCount = 1; + readonly attribute int64u upTime = 2; + readonly attribute int32u totalOperationalHours = 3; + readonly attribute enum8 bootReasons = 4; + readonly attribute ENUM8 activeHardwareFaults[] = 5; + readonly attribute ENUM8 activeRadioFaults[] = 6; + readonly attribute ENUM8 activeNetworkFaults[] = 7; + readonly attribute boolean testEventTriggersEnabled = 8; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct TestEventTriggerRequest { + OCTET_STRING<16> enableKey = 0; + INT64U eventTrigger = 1; + } + + command access(invoke: manage) TestEventTrigger(TestEventTriggerRequest): DefaultSuccess = 0; +} + +server cluster SoftwareDiagnostics = 52 { + bitmap SoftwareDiagnosticsFeature : BITMAP32 { + kWaterMarks = 0x1; + } + + struct ThreadMetrics { + int64u id = 0; + optional char_string<8> name = 1; + optional int32u stackFreeCurrent = 2; + optional int32u stackFreeMinimum = 3; + optional int32u stackSize = 4; + } + + info event SoftwareFault = 0 { + INT64U id = 0; + optional CHAR_STRING name = 1; + optional OCTET_STRING faultRecording = 2; + } + + readonly attribute ThreadMetrics threadMetrics[] = 0; + readonly attribute int64u currentHeapFree = 1; + readonly attribute int64u currentHeapUsed = 2; + readonly attribute int64u currentHeapHighWatermark = 3; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + command ResetWatermarks(): DefaultSuccess = 0; +} + +server cluster ThreadNetworkDiagnostics = 53 { + enum NetworkFault : ENUM8 { + kUnspecified = 0; + kLinkDown = 1; + kHardwareFailure = 2; + kNetworkJammed = 3; + } + + enum RoutingRole : ENUM8 { + kUnspecified = 0; + kUnassigned = 1; + kSleepyEndDevice = 2; + kEndDevice = 3; + kReed = 4; + kRouter = 5; + kLeader = 6; + } + + enum ThreadConnectionStatus : ENUM8 { + kConnected = 0; + kNotConnected = 1; + } + + bitmap ThreadNetworkDiagnosticsFeature : BITMAP32 { + kPacketCounts = 0x1; + kErrorCounts = 0x2; + kMLECounts = 0x4; + kMACCounts = 0x8; + } + + struct NeighborTable { + int64u extAddress = 0; + int32u age = 1; + int16u rloc16 = 2; + int32u linkFrameCounter = 3; + int32u mleFrameCounter = 4; + int8u lqi = 5; + nullable int8s averageRssi = 6; + nullable int8s lastRssi = 7; + int8u frameErrorRate = 8; + int8u messageErrorRate = 9; + boolean rxOnWhenIdle = 10; + boolean fullThreadDevice = 11; + boolean fullNetworkData = 12; + boolean isChild = 13; + } + + struct RouteTable { + int64u extAddress = 0; + int16u rloc16 = 1; + int8u routerId = 2; + int8u nextHop = 3; + int8u pathCost = 4; + int8u LQIIn = 5; + int8u LQIOut = 6; + int8u age = 7; + boolean allocated = 8; + boolean linkEstablished = 9; + } + + struct SecurityPolicy { + int16u rotationTime = 0; + bitmap16 flags = 1; + } + + struct OperationalDatasetComponents { + boolean activeTimestampPresent = 0; + boolean pendingTimestampPresent = 1; + boolean masterKeyPresent = 2; + boolean networkNamePresent = 3; + boolean extendedPanIdPresent = 4; + boolean meshLocalPrefixPresent = 5; + boolean delayPresent = 6; + boolean panIdPresent = 7; + boolean channelPresent = 8; + boolean pskcPresent = 9; + boolean securityPolicyPresent = 10; + boolean channelMaskPresent = 11; + } + + info event ConnectionStatus = 0 { + ThreadConnectionStatus connectionStatus = 0; + } + + info event NetworkFaultChange = 1 { + NetworkFault current[] = 0; + NetworkFault previous[] = 1; + } + + readonly attribute nullable int16u channel = 0; + readonly attribute nullable RoutingRole routingRole = 1; + readonly attribute nullable char_string<16> networkName = 2; + readonly attribute nullable int16u panId = 3; + readonly attribute nullable int64u extendedPanId = 4; + readonly attribute nullable octet_string<17> meshLocalPrefix = 5; + readonly attribute int64u overrunCount = 6; + readonly attribute NeighborTable neighborTableList[] = 7; + readonly attribute RouteTable routeTableList[] = 8; + readonly attribute nullable int32u partitionId = 9; + readonly attribute nullable int8u weighting = 10; + readonly attribute nullable int8u dataVersion = 11; + readonly attribute nullable int8u stableDataVersion = 12; + readonly attribute nullable int8u leaderRouterId = 13; + readonly attribute int16u detachedRoleCount = 14; + readonly attribute int16u childRoleCount = 15; + readonly attribute int16u routerRoleCount = 16; + readonly attribute int16u leaderRoleCount = 17; + readonly attribute int16u attachAttemptCount = 18; + readonly attribute int16u partitionIdChangeCount = 19; + readonly attribute int16u betterPartitionAttachAttemptCount = 20; + readonly attribute int16u parentChangeCount = 21; + readonly attribute int32u txTotalCount = 22; + readonly attribute int32u txUnicastCount = 23; + readonly attribute int32u txBroadcastCount = 24; + readonly attribute int32u txAckRequestedCount = 25; + readonly attribute int32u txAckedCount = 26; + readonly attribute int32u txNoAckRequestedCount = 27; + readonly attribute int32u txDataCount = 28; + readonly attribute int32u txDataPollCount = 29; + readonly attribute int32u txBeaconCount = 30; + readonly attribute int32u txBeaconRequestCount = 31; + readonly attribute int32u txOtherCount = 32; + readonly attribute int32u txRetryCount = 33; + readonly attribute int32u txDirectMaxRetryExpiryCount = 34; + readonly attribute int32u txIndirectMaxRetryExpiryCount = 35; + readonly attribute int32u txErrCcaCount = 36; + readonly attribute int32u txErrAbortCount = 37; + readonly attribute int32u txErrBusyChannelCount = 38; + readonly attribute int32u rxTotalCount = 39; + readonly attribute int32u rxUnicastCount = 40; + readonly attribute int32u rxBroadcastCount = 41; + readonly attribute int32u rxDataCount = 42; + readonly attribute int32u rxDataPollCount = 43; + readonly attribute int32u rxBeaconCount = 44; + readonly attribute int32u rxBeaconRequestCount = 45; + readonly attribute int32u rxOtherCount = 46; + readonly attribute int32u rxAddressFilteredCount = 47; + readonly attribute int32u rxDestAddrFilteredCount = 48; + readonly attribute int32u rxDuplicatedCount = 49; + readonly attribute int32u rxErrNoFrameCount = 50; + readonly attribute int32u rxErrUnknownNeighborCount = 51; + readonly attribute int32u rxErrInvalidSrcAddrCount = 52; + readonly attribute int32u rxErrSecCount = 53; + readonly attribute int32u rxErrFcsCount = 54; + readonly attribute int32u rxErrOtherCount = 55; + readonly attribute nullable int64u activeTimestamp = 56; + readonly attribute nullable int64u pendingTimestamp = 57; + readonly attribute nullable int32u delay = 58; + readonly attribute nullable SecurityPolicy securityPolicy = 59; + readonly attribute nullable octet_string<4> channelPage0Mask = 60; + readonly attribute nullable OperationalDatasetComponents operationalDatasetComponents = 61; + readonly attribute NetworkFault activeNetworkFaultsList[] = 62; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + command ResetCounts(): DefaultSuccess = 0; +} + +server cluster WiFiNetworkDiagnostics = 54 { + enum AssociationFailureCause : ENUM8 { + kUnknown = 0; + kAssociationFailed = 1; + kAuthenticationFailed = 2; + kSsidNotFound = 3; + } + + enum SecurityType : ENUM8 { + kUnspecified = 0; + kNone = 1; + kWep = 2; + kWpa = 3; + kWpa2 = 4; + kWpa3 = 5; + } + + enum WiFiConnectionStatus : ENUM8 { + kConnected = 0; + kNotConnected = 1; + } + + enum WiFiVersionType : ENUM8 { + k80211a = 0; + k80211b = 1; + k80211g = 2; + k80211n = 3; + k80211ac = 4; + k80211ax = 5; + } + + info event Disconnection = 0 { + INT16U reasonCode = 0; + } + + info event AssociationFailure = 1 { + AssociationFailureCause associationFailure = 0; + INT16U status = 1; + } + + info event ConnectionStatus = 2 { + WiFiConnectionStatus connectionStatus = 0; + } + + readonly attribute nullable octet_string<6> bssid = 0; + readonly attribute nullable SecurityType securityType = 1; + readonly attribute nullable WiFiVersionType wiFiVersion = 2; + readonly attribute nullable int16u channelNumber = 3; + readonly attribute nullable int8s rssi = 4; + readonly attribute nullable int32u beaconLostCount = 5; + readonly attribute nullable int32u beaconRxCount = 6; + readonly attribute nullable int32u packetMulticastRxCount = 7; + readonly attribute nullable int32u packetMulticastTxCount = 8; + readonly attribute nullable int32u packetUnicastRxCount = 9; + readonly attribute nullable int32u packetUnicastTxCount = 10; + readonly attribute nullable int64u currentMaxRate = 11; + readonly attribute nullable int64u overrunCount = 12; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + command ResetCounts(): DefaultSuccess = 0; +} + +server cluster EthernetNetworkDiagnostics = 55 { + enum PHYRateType : ENUM8 { + k10m = 0; + k100m = 1; + k1000m = 2; + k25g = 3; + k5g = 4; + k10g = 5; + k40g = 6; + k100g = 7; + k200g = 8; + k400g = 9; + } + + readonly attribute nullable PHYRateType PHYRate = 0; + readonly attribute nullable boolean fullDuplex = 1; + readonly attribute int64u packetRxCount = 2; + readonly attribute int64u packetTxCount = 3; + readonly attribute int64u txErrCount = 4; + readonly attribute int64u collisionCount = 5; + readonly attribute int64u overrunCount = 6; + readonly attribute nullable boolean carrierDetect = 7; + readonly attribute int64u timeSinceReset = 8; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + command ResetCounts(): DefaultSuccess = 0; +} + +server cluster AdministratorCommissioning = 60 { + enum CommissioningWindowStatus : ENUM8 { + kWindowNotOpen = 0; + kEnhancedWindowOpen = 1; + kBasicWindowOpen = 2; + } + + enum StatusCode : ENUM8 { + kBusy = 2; + kPAKEParameterError = 3; + kWindowNotOpen = 4; + } + + readonly attribute CommissioningWindowStatus windowStatus = 0; + readonly attribute nullable fabric_idx adminFabricIndex = 1; + readonly attribute nullable int16u adminVendorId = 2; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct OpenCommissioningWindowRequest { + INT16U commissioningTimeout = 0; + OCTET_STRING PAKEVerifier = 1; + INT16U discriminator = 2; + INT32U iterations = 3; + OCTET_STRING salt = 4; + } + + request struct OpenBasicCommissioningWindowRequest { + INT16U commissioningTimeout = 0; + } + + timed command access(invoke: administer) OpenCommissioningWindow(OpenCommissioningWindowRequest): DefaultSuccess = 0; + timed command access(invoke: administer) OpenBasicCommissioningWindow(OpenBasicCommissioningWindowRequest): DefaultSuccess = 1; + timed command access(invoke: administer) RevokeCommissioning(): DefaultSuccess = 2; +} + +server cluster OperationalCredentials = 62 { + enum OperationalCertStatus : ENUM8 { + kSuccess = 0; + kInvalidPublicKey = 1; + kInvalidNodeOpId = 2; + kInvalidNOC = 3; + kMissingCsr = 4; + kTableFull = 5; + kInvalidAdminSubject = 6; + kFabricConflict = 9; + kLabelConflict = 10; + kInvalidFabricIndex = 11; + } + + fabric_scoped struct NOCStruct { + fabric_sensitive octet_string noc = 1; + nullable fabric_sensitive octet_string icac = 2; + fabric_idx fabricIndex = 254; + } + + fabric_scoped struct FabricDescriptor { + octet_string<65> rootPublicKey = 1; + vendor_id vendorId = 2; + fabric_id fabricId = 3; + node_id nodeId = 4; + char_string<32> label = 5; + fabric_idx fabricIndex = 254; + } + + readonly attribute access(read: administer) NOCStruct NOCs[] = 0; + readonly attribute FabricDescriptor fabrics[] = 1; + readonly attribute int8u supportedFabrics = 2; + readonly attribute int8u commissionedFabrics = 3; + readonly attribute OCTET_STRING trustedRootCertificates[] = 4; + readonly attribute int8u currentFabricIndex = 5; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct AttestationRequestRequest { + OCTET_STRING attestationNonce = 0; + } + + request struct CertificateChainRequestRequest { + INT8U certificateType = 0; + } + + request struct CSRRequestRequest { + OCTET_STRING CSRNonce = 0; + optional boolean isForUpdateNOC = 1; + } + + request struct AddNOCRequest { + OCTET_STRING NOCValue = 0; + optional OCTET_STRING ICACValue = 1; + OCTET_STRING IPKValue = 2; + Int64u caseAdminSubject = 3; + VENDOR_ID adminVendorId = 4; + } + + request struct UpdateNOCRequest { + OCTET_STRING NOCValue = 0; + optional OCTET_STRING ICACValue = 1; + } + + request struct UpdateFabricLabelRequest { + CHAR_STRING<32> label = 0; + } + + request struct RemoveFabricRequest { + fabric_idx fabricIndex = 0; + } + + request struct AddTrustedRootCertificateRequest { + OCTET_STRING rootCertificate = 0; + } + + response struct AttestationResponse = 1 { + OCTET_STRING attestationElements = 0; + OCTET_STRING signature = 1; + } + + response struct CertificateChainResponse = 3 { + OCTET_STRING certificate = 0; + } + + response struct CSRResponse = 5 { + OCTET_STRING NOCSRElements = 0; + OCTET_STRING attestationSignature = 1; + } + + response struct NOCResponse = 8 { + OperationalCertStatus statusCode = 0; + optional fabric_idx fabricIndex = 1; + optional CHAR_STRING debugText = 2; + } + + command access(invoke: administer) AttestationRequest(AttestationRequestRequest): AttestationResponse = 0; + command access(invoke: administer) CertificateChainRequest(CertificateChainRequestRequest): CertificateChainResponse = 2; + command access(invoke: administer) CSRRequest(CSRRequestRequest): CSRResponse = 4; + command access(invoke: administer) AddNOC(AddNOCRequest): NOCResponse = 6; + fabric command access(invoke: administer) UpdateNOC(UpdateNOCRequest): NOCResponse = 7; + fabric command access(invoke: administer) UpdateFabricLabel(UpdateFabricLabelRequest): NOCResponse = 9; + command access(invoke: administer) RemoveFabric(RemoveFabricRequest): NOCResponse = 10; + command access(invoke: administer) AddTrustedRootCertificate(AddTrustedRootCertificateRequest): DefaultSuccess = 11; +} + +server cluster GroupKeyManagement = 63 { + enum GroupKeySecurityPolicy : ENUM8 { + kTrustFirst = 0; + kCacheAndSync = 1; + } + + fabric_scoped struct GroupKeyMapStruct { + group_id groupId = 1; + int16u groupKeySetID = 2; + fabric_idx fabricIndex = 254; + } + + fabric_scoped struct GroupInfoMapStruct { + group_id groupId = 1; + endpoint_no endpoints[] = 2; + optional char_string<16> groupName = 3; + fabric_idx fabricIndex = 254; + } + + struct GroupKeySetStruct { + int16u groupKeySetID = 0; + GroupKeySecurityPolicy groupKeySecurityPolicy = 1; + nullable octet_string<16> epochKey0 = 2; + nullable epoch_us epochStartTime0 = 3; + nullable octet_string<16> epochKey1 = 4; + nullable epoch_us epochStartTime1 = 5; + nullable octet_string<16> epochKey2 = 6; + nullable epoch_us epochStartTime2 = 7; + } + + attribute access(write: manage) GroupKeyMapStruct groupKeyMap[] = 0; + readonly attribute GroupInfoMapStruct groupTable[] = 1; + readonly attribute int16u maxGroupsPerFabric = 2; + readonly attribute int16u maxGroupKeysPerFabric = 3; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct KeySetWriteRequest { + GroupKeySetStruct groupKeySet = 0; + } + + request struct KeySetReadRequest { + INT16U groupKeySetID = 0; + } + + request struct KeySetRemoveRequest { + INT16U groupKeySetID = 0; + } + + request struct KeySetReadAllIndicesRequest { + INT16U groupKeySetIDs[] = 0; + } + + response struct KeySetReadResponse = 2 { + GroupKeySetStruct groupKeySet = 0; + } + + response struct KeySetReadAllIndicesResponse = 5 { + INT16U groupKeySetIDs[] = 0; + } + + fabric command access(invoke: administer) KeySetWrite(KeySetWriteRequest): DefaultSuccess = 0; + fabric command access(invoke: administer) KeySetRead(KeySetReadRequest): KeySetReadResponse = 1; + fabric command access(invoke: administer) KeySetRemove(KeySetRemoveRequest): DefaultSuccess = 3; + fabric command access(invoke: administer) KeySetReadAllIndices(KeySetReadAllIndicesRequest): KeySetReadAllIndicesResponse = 4; +} + +server cluster FixedLabel = 64 { + readonly attribute LabelStruct labelList[] = 0; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; +} + +server cluster UserLabel = 65 { + attribute access(write: manage) LabelStruct labelList[] = 0; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; +} + +server cluster BooleanState = 69 { + info event StateChange = 0 { + boolean stateValue = 0; + } + + readonly attribute boolean stateValue = 0; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; +} + +server cluster OccupancySensing = 1030 { + readonly attribute bitmap8 occupancy = 0; + readonly attribute enum8 occupancySensorType = 1; + readonly attribute bitmap8 occupancySensorTypeBitmap = 2; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; +} + +endpoint 0 { + device type rootdevice = 22; + binding cluster OtaSoftwareUpdateProvider; + + server cluster Groups { + ram attribute nameSupport; + ram attribute featureMap; + ram attribute clusterRevision default = 4; + } + + server cluster Descriptor { + callback attribute deviceTypeList; + callback attribute serverList; + callback attribute clientList; + callback attribute partsList; + ram attribute featureMap; + callback attribute clusterRevision default = 1; + } + + server cluster AccessControl { + callback attribute acl; + callback attribute extension; + callback attribute subjectsPerAccessControlEntry default = 4; + callback attribute targetsPerAccessControlEntry default = 3; + callback attribute accessControlEntriesPerFabric default = 3; + callback attribute attributeList; + ram attribute featureMap; + ram attribute clusterRevision default = 1; + } + + server cluster Basic { + callback attribute dataModelRevision default = 10; + callback attribute vendorName; + callback attribute vendorID; + callback attribute productName; + callback attribute productID; + persist attribute nodeLabel; + callback attribute location default = "XX"; + callback attribute hardwareVersion; + callback attribute hardwareVersionString; + callback attribute softwareVersion; + callback attribute softwareVersionString; + callback attribute manufacturingDate default = "20210614123456ZZ"; + callback attribute partNumber; + callback attribute productURL; + callback attribute productLabel; + callback attribute serialNumber; + persist attribute localConfigDisabled; + ram attribute reachable default = 1; + callback attribute uniqueID; + callback attribute capabilityMinima; + ram attribute featureMap; + ram attribute clusterRevision default = 1; + } + + server cluster OtaSoftwareUpdateRequestor { + callback attribute defaultOtaProviders; + ram attribute updatePossible default = 1; + ram attribute updateState; + ram attribute updateStateProgress; + ram attribute featureMap; + ram attribute clusterRevision default = 1; + } + + server cluster LocalizationConfiguration { + persist attribute activeLocale default = "en-US"; + callback attribute supportedLocales; + ram attribute featureMap; + ram attribute clusterRevision default = 1; + } + + server cluster TimeFormatLocalization { + persist attribute hourFormat; + persist attribute activeCalendarType; + callback attribute supportedCalendarTypes; + ram attribute featureMap; + ram attribute clusterRevision default = 1; + } + + server cluster GeneralCommissioning { + ram attribute breadcrumb; + callback attribute basicCommissioningInfo; + callback attribute regulatoryConfig; + callback attribute locationCapability; + callback attribute supportsConcurrentConnection default = 1; + ram attribute featureMap default = 6; + ram attribute clusterRevision default = 1; + } + + server cluster NetworkCommissioning { + ram attribute maxNetworks; + callback attribute networks; + ram attribute scanMaxTimeSeconds; + ram attribute connectMaxTimeSeconds; + ram attribute interfaceEnabled; + ram attribute lastNetworkingStatus; + ram attribute lastNetworkID; + ram attribute lastConnectErrorValue; + ram attribute featureMap default = 2; + ram attribute clusterRevision default = 1; + } + + server cluster DiagnosticLogs { + ram attribute featureMap; + ram attribute clusterRevision default = 1; + } + + server cluster GeneralDiagnostics { + callback attribute networkInterfaces; + callback attribute rebootCount; + callback attribute upTime; + callback attribute totalOperationalHours; + callback attribute bootReasons; + callback attribute activeHardwareFaults; + callback attribute activeRadioFaults; + callback attribute activeNetworkFaults; + callback attribute testEventTriggersEnabled; + ram attribute featureMap; + ram attribute clusterRevision default = 1; + } + + server cluster SoftwareDiagnostics { + callback attribute threadMetrics; + callback attribute currentHeapFree; + callback attribute currentHeapUsed; + callback attribute currentHeapHighWatermark; + ram attribute featureMap default = 1; + ram attribute clusterRevision default = 1; + } + + server cluster ThreadNetworkDiagnostics { + callback attribute channel; + callback attribute routingRole; + callback attribute networkName; + callback attribute panId; + callback attribute extendedPanId; + callback attribute meshLocalPrefix; + callback attribute overrunCount; + callback attribute neighborTableList; + callback attribute routeTableList; + callback attribute partitionId; + callback attribute weighting; + callback attribute dataVersion; + callback attribute stableDataVersion; + callback attribute leaderRouterId; + callback attribute detachedRoleCount; + callback attribute childRoleCount; + callback attribute routerRoleCount; + callback attribute leaderRoleCount; + callback attribute attachAttemptCount; + callback attribute partitionIdChangeCount; + callback attribute betterPartitionAttachAttemptCount; + callback attribute parentChangeCount; + callback attribute txTotalCount; + callback attribute txUnicastCount; + callback attribute txBroadcastCount; + callback attribute txAckRequestedCount; + callback attribute txAckedCount; + callback attribute txNoAckRequestedCount; + callback attribute txDataCount; + callback attribute txDataPollCount; + callback attribute txBeaconCount; + callback attribute txBeaconRequestCount; + callback attribute txOtherCount; + callback attribute txRetryCount; + callback attribute txDirectMaxRetryExpiryCount; + callback attribute txIndirectMaxRetryExpiryCount; + callback attribute txErrCcaCount; + callback attribute txErrAbortCount; + callback attribute txErrBusyChannelCount; + callback attribute rxTotalCount; + callback attribute rxUnicastCount; + callback attribute rxBroadcastCount; + callback attribute rxDataCount; + callback attribute rxDataPollCount; + callback attribute rxBeaconCount; + callback attribute rxBeaconRequestCount; + callback attribute rxOtherCount; + callback attribute rxAddressFilteredCount; + callback attribute rxDestAddrFilteredCount; + callback attribute rxDuplicatedCount; + callback attribute rxErrNoFrameCount; + callback attribute rxErrUnknownNeighborCount; + callback attribute rxErrInvalidSrcAddrCount; + callback attribute rxErrSecCount; + callback attribute rxErrFcsCount; + callback attribute rxErrOtherCount; + callback attribute activeTimestamp; + callback attribute pendingTimestamp; + callback attribute delay; + callback attribute securityPolicy; + callback attribute channelPage0Mask; + callback attribute operationalDatasetComponents; + callback attribute activeNetworkFaultsList; + ram attribute featureMap default = 0x000F; + ram attribute clusterRevision default = 1; + } + + server cluster WiFiNetworkDiagnostics { + callback attribute bssid; + callback attribute securityType; + callback attribute wiFiVersion; + callback attribute channelNumber; + callback attribute rssi; + callback attribute beaconLostCount; + callback attribute beaconRxCount; + callback attribute packetMulticastRxCount; + callback attribute packetMulticastTxCount; + callback attribute packetUnicastRxCount; + callback attribute packetUnicastTxCount; + callback attribute currentMaxRate; + callback attribute overrunCount; + ram attribute featureMap default = 3; + ram attribute clusterRevision default = 1; + } + + server cluster EthernetNetworkDiagnostics { + callback attribute PHYRate; + callback attribute fullDuplex; + callback attribute packetRxCount; + callback attribute packetTxCount; + callback attribute txErrCount; + callback attribute collisionCount; + callback attribute overrunCount; + callback attribute carrierDetect; + callback attribute timeSinceReset; + ram attribute featureMap default = 3; + ram attribute clusterRevision default = 1; + } + + server cluster AdministratorCommissioning { + callback attribute windowStatus; + callback attribute adminFabricIndex default = 1; + callback attribute adminVendorId; + ram attribute featureMap; + ram attribute clusterRevision default = 1; + } + + server cluster OperationalCredentials { + callback attribute NOCs; + callback attribute fabrics; + callback attribute supportedFabrics; + callback attribute commissionedFabrics; + callback attribute trustedRootCertificates; + callback attribute currentFabricIndex; + ram attribute featureMap; + ram attribute clusterRevision default = 1; + } + + server cluster GroupKeyManagement { + callback attribute groupKeyMap; + callback attribute groupTable; + callback attribute maxGroupsPerFabric; + callback attribute maxGroupKeysPerFabric; + ram attribute featureMap; + ram attribute clusterRevision default = 1; + } + + server cluster FixedLabel { + callback attribute labelList; + ram attribute featureMap; + ram attribute clusterRevision default = 1; + } + + server cluster UserLabel { + callback attribute labelList; + ram attribute featureMap; + ram attribute clusterRevision default = 1; + } +} +endpoint 1 { + device type dimmablelight = 21; + + server cluster Identify { + ram attribute identifyTime; + ram attribute identifyType; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute attributeList; + ram attribute featureMap; + ram attribute clusterRevision default = 4; + } + + server cluster Descriptor { + callback attribute deviceTypeList; + callback attribute serverList; + callback attribute clientList; + callback attribute partsList; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute attributeList; + ram attribute featureMap; + callback attribute clusterRevision default = 1; + } + + server cluster BooleanState { + ram attribute stateValue; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute attributeList; + ram attribute featureMap; + ram attribute clusterRevision default = 1; + } + + server cluster OccupancySensing { + ram attribute occupancy; + ram attribute occupancySensorType; + ram attribute occupancySensorTypeBitmap; + ram attribute featureMap; + ram attribute clusterRevision default = 3; + } +} + + diff --git a/examples/contact-sensor-app/contact-sensor-common/contact-sensor-app.zap b/examples/contact-sensor-app/contact-sensor-common/contact-sensor-app.zap new file mode 100644 index 00000000000000..9d67cf3e88528e --- /dev/null +++ b/examples/contact-sensor-app/contact-sensor-common/contact-sensor-app.zap @@ -0,0 +1,8687 @@ +{ + "featureLevel": 81, + "creator": "zap", + "keyValuePairs": [ + { + "key": "commandDiscovery", + "value": "1" + }, + { + "key": "defaultResponsePolicy", + "value": "always" + }, + { + "key": "manufacturerCodes", + "value": "0x1002" + } + ], + "package": [ + { + "pathRelativity": "relativeToZap", + "path": "../../../src/app/zap-templates/zcl/zcl.json", + "type": "zcl-properties", + "category": "matter", + "version": 1, + "description": "Matter SDK ZCL data" + }, + { + "pathRelativity": "relativeToZap", + "path": "../../../src/app/zap-templates/app-templates.json", + "type": "gen-templates-json", + "version": "chip-v1" + } + ], + "endpointTypes": [ + { + "name": "MA-rootdevice", + "deviceTypeName": "MA-rootdevice", + "deviceTypeCode": 22, + "deviceTypeProfileId": 259, + "clusters": [ + { + "name": "Identify", + "code": 3, + "mfgCode": null, + "define": "IDENTIFY_CLUSTER", + "side": "client", + "enabled": 0, + "commands": [ + { + "name": "Identify", + "code": 0, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + } + ], + "attributes": [ + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "client", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "4", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Identify", + "code": 3, + "mfgCode": null, + "define": "IDENTIFY_CLUSTER", + "side": "server", + "enabled": 0, + "attributes": [ + { + "name": "identify time", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "4", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Groups", + "code": 4, + "mfgCode": null, + "define": "GROUPS_CLUSTER", + "side": "client", + "enabled": 0, + "commands": [ + { + "name": "AddGroup", + "code": 0, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "ViewGroup", + "code": 1, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "GetGroupMembership", + "code": 2, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "RemoveGroup", + "code": 3, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "RemoveAllGroups", + "code": 4, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "AddGroupIfIdentifying", + "code": 5, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + } + ], + "attributes": [ + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "client", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "4", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Groups", + "code": 4, + "mfgCode": null, + "define": "GROUPS_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "AddGroupResponse", + "code": 0, + "mfgCode": null, + "source": "server", + "incoming": 0, + "outgoing": 1 + }, + { + "name": "ViewGroupResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "incoming": 0, + "outgoing": 1 + }, + { + "name": "GetGroupMembershipResponse", + "code": 2, + "mfgCode": null, + "source": "server", + "incoming": 0, + "outgoing": 1 + }, + { + "name": "RemoveGroupResponse", + "code": 3, + "mfgCode": null, + "source": "server", + "incoming": 0, + "outgoing": 1 + } + ], + "attributes": [ + { + "name": "name support", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "bitmap8", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "4", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Scenes", + "code": 5, + "mfgCode": null, + "define": "SCENES_CLUSTER", + "side": "client", + "enabled": 0, + "commands": [ + { + "name": "AddScene", + "code": 0, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "ViewScene", + "code": 1, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "RemoveScene", + "code": 2, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "RemoveAllScenes", + "code": 3, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "StoreScene", + "code": 4, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "RecallScene", + "code": 5, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "GetSceneMembership", + "code": 6, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + } + ], + "attributes": [ + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "client", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "4", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Scenes", + "code": 5, + "mfgCode": null, + "define": "SCENES_CLUSTER", + "side": "server", + "enabled": 0, + "commands": [ + { + "name": "AddSceneResponse", + "code": 0, + "mfgCode": null, + "source": "server", + "incoming": 0, + "outgoing": 1 + }, + { + "name": "ViewSceneResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "incoming": 0, + "outgoing": 1 + }, + { + "name": "RemoveSceneResponse", + "code": 2, + "mfgCode": null, + "source": "server", + "incoming": 0, + "outgoing": 1 + }, + { + "name": "RemoveAllScenesResponse", + "code": 3, + "mfgCode": null, + "source": "server", + "incoming": 0, + "outgoing": 1 + }, + { + "name": "StoreSceneResponse", + "code": 4, + "mfgCode": null, + "source": "server", + "incoming": 0, + "outgoing": 1 + }, + { + "name": "GetSceneMembershipResponse", + "code": 6, + "mfgCode": null, + "source": "server", + "incoming": 0, + "outgoing": 1 + } + ], + "attributes": [ + { + "name": "SceneCount", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "CurrentScene", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "CurrentGroup", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "group_id", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "SceneValid", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "NameSupport", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "bitmap8", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "4", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "On/Off", + "code": 6, + "mfgCode": null, + "define": "ON_OFF_CLUSTER", + "side": "client", + "enabled": 0, + "commands": [ + { + "name": "Off", + "code": 0, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "On", + "code": 1, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "Toggle", + "code": 2, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + } + ], + "attributes": [ + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "client", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "4", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "On/Off", + "code": 6, + "mfgCode": null, + "define": "ON_OFF_CLUSTER", + "side": "server", + "enabled": 0, + "attributes": [ + { + "name": "OnOff", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "4", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "On/off Switch Configuration", + "code": 7, + "mfgCode": null, + "define": "ON_OFF_SWITCH_CONFIG_CLUSTER", + "side": "client", + "enabled": 0, + "attributes": [ + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "client", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "On/off Switch Configuration", + "code": 7, + "mfgCode": null, + "define": "ON_OFF_SWITCH_CONFIG_CLUSTER", + "side": "server", + "enabled": 0, + "attributes": [ + { + "name": "switch type", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "enum8", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "switch actions", + "code": 16, + "mfgCode": null, + "side": "server", + "type": "enum8", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Level Control", + "code": 8, + "mfgCode": null, + "define": "LEVEL_CONTROL_CLUSTER", + "side": "client", + "enabled": 0, + "commands": [ + { + "name": "MoveToLevel", + "code": 0, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "Move", + "code": 1, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "Step", + "code": 2, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "Stop", + "code": 3, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "MoveToLevelWithOnOff", + "code": 4, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "MoveWithOnOff", + "code": 5, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "StepWithOnOff", + "code": 6, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "StopWithOnOff", + "code": 7, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + } + ], + "attributes": [ + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "client", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "5", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Level Control", + "code": 8, + "mfgCode": null, + "define": "LEVEL_CONTROL_CLUSTER", + "side": "server", + "enabled": 0, + "attributes": [ + { + "name": "CurrentLevel", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "5", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Descriptor", + "code": 29, + "mfgCode": null, + "define": "DESCRIPTOR_CLUSTER", + "side": "client", + "enabled": 0, + "attributes": [ + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "client", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "Descriptor", + "code": 29, + "mfgCode": null, + "define": "DESCRIPTOR_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "DeviceTypeList", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ServerList", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClientList", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "PartsList", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "Access Control", + "code": 31, + "mfgCode": null, + "define": "ACCESS_CONTROL_CLUSTER", + "side": "client", + "enabled": 0, + "attributes": [ + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "client", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "Access Control", + "code": 31, + "mfgCode": null, + "define": "ACCESS_CONTROL_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "ACL", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Extension", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "SubjectsPerAccessControlEntry", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "4", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "TargetsPerAccessControlEntry", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "3", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AccessControlEntriesPerFabric", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "3", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "Basic", + "code": 40, + "mfgCode": null, + "define": "BASIC_CLUSTER", + "side": "client", + "enabled": 0, + "attributes": [ + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "client", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 1, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Basic", + "code": 40, + "mfgCode": null, + "define": "BASIC_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "DataModelRevision", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": "10", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "VendorName", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "VendorID", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "vendor_id", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ProductName", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ProductID", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "NodeLabel", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "NVM", + "singleton": 1, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "Location", + "code": 6, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": "XX", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "HardwareVersion", + "code": 7, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "HardwareVersionString", + "code": 8, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "SoftwareVersion", + "code": 9, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "SoftwareVersionString", + "code": 10, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ManufacturingDate", + "code": 11, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": "20210614123456ZZ", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "PartNumber", + "code": 12, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ProductURL", + "code": 13, + "mfgCode": null, + "side": "server", + "type": "long_char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ProductLabel", + "code": 14, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "SerialNumber", + "code": 15, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "LocalConfigDisabled", + "code": 16, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "NVM", + "singleton": 1, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "Reachable", + "code": 17, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "RAM", + "singleton": 1, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "UniqueID", + "code": 18, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "CapabilityMinima", + "code": 19, + "mfgCode": null, + "side": "server", + "type": "CapabilityMinimaStruct", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 1, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "OTA Software Update Provider", + "code": 41, + "mfgCode": null, + "define": "OTA_PROVIDER_CLUSTER", + "side": "client", + "enabled": 1, + "commands": [ + { + "name": "QueryImage", + "code": 0, + "mfgCode": null, + "source": "client", + "incoming": 0, + "outgoing": 1 + }, + { + "name": "ApplyUpdateRequest", + "code": 2, + "mfgCode": null, + "source": "client", + "incoming": 0, + "outgoing": 1 + }, + { + "name": "NotifyUpdateApplied", + "code": 4, + "mfgCode": null, + "source": "client", + "incoming": 0, + "outgoing": 1 + } + ], + "attributes": [ + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "client", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "OTA Software Update Provider", + "code": 41, + "mfgCode": null, + "define": "OTA_PROVIDER_CLUSTER", + "side": "server", + "enabled": 0, + "commands": [ + { + "name": "QueryImageResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "ApplyUpdateResponse", + "code": 3, + "mfgCode": null, + "source": "server", + "incoming": 1, + "outgoing": 0 + } + ], + "attributes": [ + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 0, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 0, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "OTA Software Update Requestor", + "code": 42, + "mfgCode": null, + "define": "OTA_REQUESTOR_CLUSTER", + "side": "client", + "enabled": 0, + "commands": [ + { + "name": "AnnounceOtaProvider", + "code": 0, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + } + ], + "attributes": [ + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "client", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "OTA Software Update Requestor", + "code": 42, + "mfgCode": null, + "define": "OTA_REQUESTOR_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "DefaultOtaProviders", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "UpdatePossible", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "UpdateState", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "OTAUpdateStateEnum", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "UpdateStateProgress", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 0, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Localization Configuration", + "code": 43, + "mfgCode": null, + "define": "LOCALIZATION_CONFIGURATION_CLUSTER", + "side": "client", + "enabled": 0 + }, + { + "name": "Localization Configuration", + "code": 43, + "mfgCode": null, + "define": "LOCALIZATION_CONFIGURATION_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "ActiveLocale", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "NVM", + "singleton": 0, + "bounded": 0, + "defaultValue": "en-US", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "SupportedLocales", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "Time Format Localization", + "code": 44, + "mfgCode": null, + "define": "TIME_FORMAT_LOCALIZATION_CLUSTER", + "side": "client", + "enabled": 0 + }, + { + "name": "Time Format Localization", + "code": 44, + "mfgCode": null, + "define": "TIME_FORMAT_LOCALIZATION_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "HourFormat", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "HourFormat", + "included": 1, + "storageOption": "NVM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ActiveCalendarType", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "CalendarType", + "included": 1, + "storageOption": "NVM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "SupportedCalendarTypes", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "Unit Localization", + "code": 45, + "mfgCode": null, + "define": "UNIT_LOCALIZATION_CLUSTER", + "side": "client", + "enabled": 0 + }, + { + "name": "Unit Localization", + "code": 45, + "mfgCode": null, + "define": "UNIT_LOCALIZATION_CLUSTER", + "side": "server", + "enabled": 0, + "attributes": [ + { + "name": "TemperatureUnit", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "TempUnit", + "included": 0, + "storageOption": "NVM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "General Commissioning", + "code": 48, + "mfgCode": null, + "define": "GENERAL_COMMISSIONING_CLUSTER", + "side": "client", + "enabled": 0, + "commands": [ + { + "name": "ArmFailSafe", + "code": 0, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "SetRegulatoryConfig", + "code": 2, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "CommissioningComplete", + "code": 4, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + } + ], + "attributes": [ + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "client", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "General Commissioning", + "code": 48, + "mfgCode": null, + "define": "GENERAL_COMMISSIONING_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "ArmFailSafeResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "SetRegulatoryConfigResponse", + "code": 3, + "mfgCode": null, + "source": "server", + "incoming": 0, + "outgoing": 1 + }, + { + "name": "CommissioningCompleteResponse", + "code": 5, + "mfgCode": null, + "source": "server", + "incoming": 1, + "outgoing": 1 + } + ], + "attributes": [ + { + "name": "Breadcrumb", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000000000000000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "BasicCommissioningInfo", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "BasicCommissioningInfo", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RegulatoryConfig", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "RegulatoryLocationType", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "LocationCapability", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "RegulatoryLocationType", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "SupportsConcurrentConnection", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "6", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Network Commissioning", + "code": 49, + "mfgCode": null, + "define": "NETWORK_COMMISSIONING_CLUSTER", + "side": "client", + "enabled": 0, + "commands": [ + { + "name": "ScanNetworks", + "code": 0, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "AddOrUpdateWiFiNetwork", + "code": 2, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "AddOrUpdateThreadNetwork", + "code": 3, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "RemoveNetwork", + "code": 4, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "ConnectNetwork", + "code": 6, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "ReorderNetwork", + "code": 8, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + } + ], + "attributes": [ + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "client", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Network Commissioning", + "code": 49, + "mfgCode": null, + "define": "NETWORK_COMMISSIONING_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "ScanNetworksResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "NetworkConfigResponse", + "code": 5, + "mfgCode": null, + "source": "server", + "incoming": 0, + "outgoing": 1 + }, + { + "name": "ConnectNetworkResponse", + "code": 7, + "mfgCode": null, + "source": "server", + "incoming": 0, + "outgoing": 1 + } + ], + "attributes": [ + { + "name": "MaxNetworks", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Networks", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ScanMaxTimeSeconds", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ConnectMaxTimeSeconds", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "InterfaceEnabled", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "LastNetworkingStatus", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "NetworkCommissioningStatus", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "LastNetworkID", + "code": 6, + "mfgCode": null, + "side": "server", + "type": "octet_string", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "LastConnectErrorValue", + "code": 7, + "mfgCode": null, + "side": "server", + "type": "int32s", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "2", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Diagnostic Logs", + "code": 50, + "mfgCode": null, + "define": "DIAGNOSTIC_LOGS_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "RetrieveLogsRequest", + "code": 0, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + } + ], + "attributes": [ + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "General Diagnostics", + "code": 51, + "mfgCode": null, + "define": "GENERAL_DIAGNOSTICS_CLUSTER", + "side": "client", + "enabled": 0, + "attributes": [ + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "client", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "General Diagnostics", + "code": 51, + "mfgCode": null, + "define": "GENERAL_DIAGNOSTICS_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "TestEventTrigger", + "code": 0, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + } + ], + "attributes": [ + { + "name": "NetworkInterfaces", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RebootCount", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "UpTime", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000000000000000", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "TotalOperationalHours", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00000000", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "BootReasons", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "enum8", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ActiveHardwareFaults", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ActiveRadioFaults", + "code": 6, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ActiveNetworkFaults", + "code": 7, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "TestEventTriggersEnabled", + "code": 8, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "false", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Software Diagnostics", + "code": 52, + "mfgCode": null, + "define": "SOFTWARE_DIAGNOSTICS_CLUSTER", + "side": "client", + "enabled": 0, + "commands": [ + { + "name": "ResetWatermarks", + "code": 0, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + } + ], + "attributes": [ + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "client", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Software Diagnostics", + "code": 52, + "mfgCode": null, + "define": "SOFTWARE_DIAGNOSTICS_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "ThreadMetrics", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "CurrentHeapFree", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000000000000000", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "CurrentHeapUsed", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000000000000000", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "CurrentHeapHighWatermark", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000000000000000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Thread Network Diagnostics", + "code": 53, + "mfgCode": null, + "define": "THREAD_NETWORK_DIAGNOSTICS_CLUSTER", + "side": "client", + "enabled": 0, + "commands": [ + { + "name": "ResetCounts", + "code": 0, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + } + ], + "attributes": [ + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "client", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Thread Network Diagnostics", + "code": 53, + "mfgCode": null, + "define": "THREAD_NETWORK_DIAGNOSTICS_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "channel", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RoutingRole", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "RoutingRole", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "NetworkName", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "PanId", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ExtendedPanId", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000000000000000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "MeshLocalPrefix", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "octet_string", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "OverrunCount", + "code": 6, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000000000000000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "NeighborTableList", + "code": 7, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RouteTableList", + "code": 8, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "PartitionId", + "code": 9, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "weighting", + "code": 10, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "DataVersion", + "code": 11, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "StableDataVersion", + "code": 12, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "LeaderRouterId", + "code": 13, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "DetachedRoleCount", + "code": 14, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ChildRoleCount", + "code": 15, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RouterRoleCount", + "code": 16, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "LeaderRoleCount", + "code": 17, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "AttachAttemptCount", + "code": 18, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "PartitionIdChangeCount", + "code": 19, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "BetterPartitionAttachAttemptCount", + "code": 20, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ParentChangeCount", + "code": 21, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxTotalCount", + "code": 22, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxUnicastCount", + "code": 23, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxBroadcastCount", + "code": 24, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxAckRequestedCount", + "code": 25, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxAckedCount", + "code": 26, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxNoAckRequestedCount", + "code": 27, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxDataCount", + "code": 28, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxDataPollCount", + "code": 29, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxBeaconCount", + "code": 30, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxBeaconRequestCount", + "code": 31, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxOtherCount", + "code": 32, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxRetryCount", + "code": 33, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxDirectMaxRetryExpiryCount", + "code": 34, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxIndirectMaxRetryExpiryCount", + "code": 35, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxErrCcaCount", + "code": 36, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxErrAbortCount", + "code": 37, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxErrBusyChannelCount", + "code": 38, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxTotalCount", + "code": 39, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxUnicastCount", + "code": 40, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxBroadcastCount", + "code": 41, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxDataCount", + "code": 42, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxDataPollCount", + "code": 43, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxBeaconCount", + "code": 44, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxBeaconRequestCount", + "code": 45, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxOtherCount", + "code": 46, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxAddressFilteredCount", + "code": 47, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxDestAddrFilteredCount", + "code": 48, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxDuplicatedCount", + "code": 49, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxErrNoFrameCount", + "code": 50, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxErrUnknownNeighborCount", + "code": 51, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxErrInvalidSrcAddrCount", + "code": 52, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxErrSecCount", + "code": 53, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxErrFcsCount", + "code": 54, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxErrOtherCount", + "code": 55, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ActiveTimestamp", + "code": 56, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000000000000000", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "PendingTimestamp", + "code": 57, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000000000000000", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Delay", + "code": 58, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "SecurityPolicy", + "code": 59, + "mfgCode": null, + "side": "server", + "type": "SecurityPolicy", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ChannelPage0Mask", + "code": 60, + "mfgCode": null, + "side": "server", + "type": "octet_string", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "OperationalDatasetComponents", + "code": 61, + "mfgCode": null, + "side": "server", + "type": "OperationalDatasetComponents", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ActiveNetworkFaultsList", + "code": 62, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x000F", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "WiFi Network Diagnostics", + "code": 54, + "mfgCode": null, + "define": "WIFI_NETWORK_DIAGNOSTICS_CLUSTER", + "side": "client", + "enabled": 0, + "commands": [ + { + "name": "ResetCounts", + "code": 0, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + } + ], + "attributes": [ + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "client", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "WiFi Network Diagnostics", + "code": 54, + "mfgCode": null, + "define": "WIFI_NETWORK_DIAGNOSTICS_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "bssid", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "octet_string", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "SecurityType", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "SecurityType", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "WiFiVersion", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "WiFiVersionType", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ChannelNumber", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "Rssi", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "int8s", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "BeaconLostCount", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00000000", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "BeaconRxCount", + "code": 6, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00000000", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "PacketMulticastRxCount", + "code": 7, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00000000", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "PacketMulticastTxCount", + "code": 8, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00000000", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "PacketUnicastRxCount", + "code": 9, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00000000", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "PacketUnicastTxCount", + "code": 10, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00000000", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "CurrentMaxRate", + "code": 11, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000000000000000", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "OverrunCount", + "code": 12, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000000000000000", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "3", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Ethernet Network Diagnostics", + "code": 55, + "mfgCode": null, + "define": "ETHERNET_NETWORK_DIAGNOSTICS_CLUSTER", + "side": "client", + "enabled": 0, + "commands": [ + { + "name": "ResetCounts", + "code": 0, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + } + ], + "attributes": [ + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "client", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Ethernet Network Diagnostics", + "code": 55, + "mfgCode": null, + "define": "ETHERNET_NETWORK_DIAGNOSTICS_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "PHYRate", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "PHYRateType", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FullDuplex", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "PacketRxCount", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000000000000000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "PacketTxCount", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000000000000000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxErrCount", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000000000000000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "CollisionCount", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000000000000000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "OverrunCount", + "code": 6, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000000000000000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "CarrierDetect", + "code": 7, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "TimeSinceReset", + "code": 8, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000000000000000", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "3", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Switch", + "code": 59, + "mfgCode": null, + "define": "SWITCH_CLUSTER", + "side": "client", + "enabled": 0 + }, + { + "name": "Switch", + "code": 59, + "mfgCode": null, + "define": "SWITCH_CLUSTER", + "side": "server", + "enabled": 0, + "attributes": [ + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "AdministratorCommissioning", + "code": 60, + "mfgCode": null, + "define": "ADMINISTRATOR_COMMISSIONING_CLUSTER", + "side": "client", + "enabled": 0, + "commands": [ + { + "name": "OpenCommissioningWindow", + "code": 0, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "OpenBasicCommissioningWindow", + "code": 1, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "RevokeCommissioning", + "code": 2, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + } + ], + "attributes": [ + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "client", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "AdministratorCommissioning", + "code": 60, + "mfgCode": null, + "define": "ADMINISTRATOR_COMMISSIONING_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "WindowStatus", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "CommissioningWindowStatus", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AdminFabricIndex", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "fabric_idx", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AdminVendorId", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Operational Credentials", + "code": 62, + "mfgCode": null, + "define": "OPERATIONAL_CREDENTIALS_CLUSTER", + "side": "client", + "enabled": 0, + "commands": [ + { + "name": "AttestationRequest", + "code": 0, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "CertificateChainRequest", + "code": 2, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "CSRRequest", + "code": 4, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "AddNOC", + "code": 6, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "UpdateNOC", + "code": 7, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "UpdateFabricLabel", + "code": 9, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "RemoveFabric", + "code": 10, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "AddTrustedRootCertificate", + "code": 11, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + } + ], + "attributes": [ + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "client", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Operational Credentials", + "code": 62, + "mfgCode": null, + "define": "OPERATIONAL_CREDENTIALS_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "AttestationResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "CertificateChainResponse", + "code": 3, + "mfgCode": null, + "source": "server", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "CSRResponse", + "code": 5, + "mfgCode": null, + "source": "server", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "NOCResponse", + "code": 8, + "mfgCode": null, + "source": "server", + "incoming": 1, + "outgoing": 1 + } + ], + "attributes": [ + { + "name": "NOCs", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Fabrics", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "SupportedFabrics", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "CommissionedFabrics", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TrustedRootCertificates", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "CurrentFabricIndex", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Group Key Management", + "code": 63, + "mfgCode": null, + "define": "GROUP_KEY_MANAGEMENT_CLUSTER", + "side": "client", + "enabled": 0, + "commands": [ + { + "name": "KeySetWrite", + "code": 0, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "KeySetRead", + "code": 1, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "KeySetRemove", + "code": 3, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "KeySetReadAllIndices", + "code": 4, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + } + ] + }, + { + "name": "Group Key Management", + "code": 63, + "mfgCode": null, + "define": "GROUP_KEY_MANAGEMENT_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "KeySetReadResponse", + "code": 2, + "mfgCode": null, + "source": "server", + "incoming": 0, + "outgoing": 1 + }, + { + "name": "KeySetReadAllIndicesResponse", + "code": 5, + "mfgCode": null, + "source": "server", + "incoming": 0, + "outgoing": 1 + } + ], + "attributes": [ + { + "name": "GroupKeyMap", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GroupTable", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "MaxGroupsPerFabric", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "MaxGroupKeysPerFabric", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "Fixed Label", + "code": 64, + "mfgCode": null, + "define": "FIXED_LABEL_CLUSTER", + "side": "client", + "enabled": 0 + }, + { + "name": "Fixed Label", + "code": 64, + "mfgCode": null, + "define": "FIXED_LABEL_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "label list", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "User Label", + "code": 65, + "mfgCode": null, + "define": "USER_LABEL_CLUSTER", + "side": "client", + "enabled": 0 + }, + { + "name": "User Label", + "code": 65, + "mfgCode": null, + "define": "USER_LABEL_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "label list", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + } + ] + }, + { + "name": "MA-dimmablelight", + "deviceTypeName": "MA-contactsensor", + "deviceTypeCode": 21, + "deviceTypeProfileId": 259, + "clusters": [ + { + "name": "Identify", + "code": 3, + "mfgCode": null, + "define": "IDENTIFY_CLUSTER", + "side": "client", + "enabled": 0, + "commands": [ + { + "name": "Identify", + "code": 0, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "TriggerEffect", + "code": 64, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + } + ], + "attributes": [ + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "client", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "client", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "4", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Identify", + "code": 3, + "mfgCode": null, + "define": "IDENTIFY_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "identify time", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "identify type", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "enum8", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "4", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Groups", + "code": 4, + "mfgCode": null, + "define": "GROUPS_CLUSTER", + "side": "client", + "enabled": 0, + "commands": [ + { + "name": "AddGroup", + "code": 0, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "ViewGroup", + "code": 1, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "GetGroupMembership", + "code": 2, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "RemoveGroup", + "code": 3, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "RemoveAllGroups", + "code": 4, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "AddGroupIfIdentifying", + "code": 5, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + } + ], + "attributes": [ + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "client", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "client", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "4", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Groups", + "code": 4, + "mfgCode": null, + "define": "GROUPS_CLUSTER", + "side": "server", + "enabled": 0, + "commands": [ + { + "name": "AddGroupResponse", + "code": 0, + "mfgCode": null, + "source": "server", + "incoming": 0, + "outgoing": 1 + }, + { + "name": "ViewGroupResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "incoming": 0, + "outgoing": 1 + }, + { + "name": "GetGroupMembershipResponse", + "code": 2, + "mfgCode": null, + "source": "server", + "incoming": 0, + "outgoing": 1 + }, + { + "name": "RemoveGroupResponse", + "code": 3, + "mfgCode": null, + "source": "server", + "incoming": 0, + "outgoing": 1 + } + ], + "attributes": [ + { + "name": "name support", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "bitmap8", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "4", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Scenes", + "code": 5, + "mfgCode": null, + "define": "SCENES_CLUSTER", + "side": "client", + "enabled": 0, + "commands": [ + { + "name": "AddScene", + "code": 0, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "ViewScene", + "code": 1, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "RemoveScene", + "code": 2, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "RemoveAllScenes", + "code": 3, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "StoreScene", + "code": 4, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "RecallScene", + "code": 5, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "GetSceneMembership", + "code": 6, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "EnhancedAddScene", + "code": 64, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "EnhancedViewScene", + "code": 65, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "CopyScene", + "code": 66, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + } + ], + "attributes": [ + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "client", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "4", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Scenes", + "code": 5, + "mfgCode": null, + "define": "SCENES_CLUSTER", + "side": "server", + "enabled": 0, + "commands": [ + { + "name": "AddSceneResponse", + "code": 0, + "mfgCode": null, + "source": "server", + "incoming": 0, + "outgoing": 1 + }, + { + "name": "ViewSceneResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "incoming": 0, + "outgoing": 1 + }, + { + "name": "RemoveSceneResponse", + "code": 2, + "mfgCode": null, + "source": "server", + "incoming": 0, + "outgoing": 1 + }, + { + "name": "RemoveAllScenesResponse", + "code": 3, + "mfgCode": null, + "source": "server", + "incoming": 0, + "outgoing": 1 + }, + { + "name": "StoreSceneResponse", + "code": 4, + "mfgCode": null, + "source": "server", + "incoming": 0, + "outgoing": 1 + }, + { + "name": "GetSceneMembershipResponse", + "code": 6, + "mfgCode": null, + "source": "server", + "incoming": 0, + "outgoing": 1 + } + ], + "attributes": [ + { + "name": "SceneCount", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "CurrentScene", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "CurrentGroup", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "group_id", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "SceneValid", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "NameSupport", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "bitmap8", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "4", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "On/Off", + "code": 6, + "mfgCode": null, + "define": "ON_OFF_CLUSTER", + "side": "client", + "enabled": 0, + "commands": [ + { + "name": "Off", + "code": 0, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "On", + "code": 1, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "Toggle", + "code": 2, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "OffWithEffect", + "code": 64, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "OnWithRecallGlobalScene", + "code": 65, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "OnWithTimedOff", + "code": 66, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + } + ], + "attributes": [ + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "client", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "4", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "On/Off", + "code": 6, + "mfgCode": null, + "define": "ON_OFF_CLUSTER", + "side": "server", + "enabled": 0, + "attributes": [ + { + "name": "OnOff", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "NVM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "GlobalSceneControl", + "code": 16384, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x01", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "OnTime", + "code": 16385, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "OffWaitTime", + "code": 16386, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "StartUpOnOff", + "code": 16387, + "mfgCode": null, + "side": "server", + "type": "OnOffStartUpOnOff", + "included": 1, + "storageOption": "NVM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0xFF", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "4", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Level Control", + "code": 8, + "mfgCode": null, + "define": "LEVEL_CONTROL_CLUSTER", + "side": "client", + "enabled": 0, + "commands": [ + { + "name": "MoveToLevel", + "code": 0, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "Move", + "code": 1, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "Step", + "code": 2, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "Stop", + "code": 3, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "MoveToLevelWithOnOff", + "code": 4, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "MoveWithOnOff", + "code": 5, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "StepWithOnOff", + "code": 6, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "StopWithOnOff", + "code": 7, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + } + ], + "attributes": [ + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "client", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "5", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Level Control", + "code": 8, + "mfgCode": null, + "define": "LEVEL_CONTROL_CLUSTER", + "side": "server", + "enabled": 0, + "attributes": [ + { + "name": "CurrentLevel", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "NVM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x01", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RemainingTime", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "MinLevel", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "MaxLevel", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0xFE", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "CurrentFrequency", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "MinFrequency", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "MaxFrequency", + "code": 6, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Options", + "code": 15, + "mfgCode": null, + "side": "server", + "type": "bitmap8", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "OnOffTransitionTime", + "code": 16, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "OnLevel", + "code": 17, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0xFF", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "OnTransitionTime", + "code": 18, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "OffTransitionTime", + "code": 19, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "DefaultMoveRate", + "code": 20, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "50", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "StartUpCurrentLevel", + "code": 16384, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "NVM", + "singleton": 0, + "bounded": 0, + "defaultValue": "255", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 0, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 0, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 0, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "3", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "5", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Descriptor", + "code": 29, + "mfgCode": null, + "define": "DESCRIPTOR_CLUSTER", + "side": "client", + "enabled": 0, + "attributes": [ + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "client", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "client", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "Descriptor", + "code": 29, + "mfgCode": null, + "define": "DESCRIPTOR_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "DeviceTypeList", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ServerList", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClientList", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "PartsList", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "Binding", + "code": 30, + "mfgCode": null, + "define": "BINDING_CLUSTER", + "side": "client", + "enabled": 0, + "attributes": [ + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "client", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "client", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "Binding", + "code": 30, + "mfgCode": null, + "define": "BINDING_CLUSTER", + "side": "server", + "enabled": 0, + "attributes": [ + { + "name": "Binding", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "Basic", + "code": 40, + "mfgCode": null, + "define": "BASIC_CLUSTER", + "side": "client", + "enabled": 0, + "attributes": [ + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "client", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 1, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Basic", + "code": 40, + "mfgCode": null, + "define": "BASIC_CLUSTER", + "side": "server", + "enabled": 0, + "attributes": [ + { + "name": "DataModelRevision", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": "10", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "VendorName", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "VendorID", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "vendor_id", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ProductName", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ProductID", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "NodeLabel", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "NVM", + "singleton": 1, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "Location", + "code": 6, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": "XX", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "HardwareVersion", + "code": 7, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "HardwareVersionString", + "code": 8, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "SoftwareVersion", + "code": 9, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "SoftwareVersionString", + "code": 10, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ManufacturingDate", + "code": 11, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": "20210614123456ZZ", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "PartNumber", + "code": 12, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ProductURL", + "code": 13, + "mfgCode": null, + "side": "server", + "type": "long_char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ProductLabel", + "code": 14, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "SerialNumber", + "code": 15, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "LocalConfigDisabled", + "code": 16, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "NVM", + "singleton": 1, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "Reachable", + "code": 17, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "RAM", + "singleton": 1, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "UniqueID", + "code": 18, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "CapabilityMinima", + "code": 19, + "mfgCode": null, + "side": "server", + "type": "CapabilityMinimaStruct", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 1, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Boolean State", + "code": 69, + "mfgCode": null, + "define": "BOOLEAN_STATE_CLUSTER", + "side": "client", + "enabled": 0, + "attributes": [ + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "client", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "client", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "Boolean State", + "code": 69, + "mfgCode": null, + "define": "BOOLEAN_STATE_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "StateValue", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "Color Control", + "code": 768, + "mfgCode": null, + "define": "COLOR_CONTROL_CLUSTER", + "side": "client", + "enabled": 0, + "commands": [ + { + "name": "MoveToHue", + "code": 0, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "MoveHue", + "code": 1, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "StepHue", + "code": 2, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "MoveToSaturation", + "code": 3, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "MoveSaturation", + "code": 4, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "StepSaturation", + "code": 5, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "MoveToHueAndSaturation", + "code": 6, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "MoveToColor", + "code": 7, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "MoveColor", + "code": 8, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "StepColor", + "code": 9, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 1 + }, + { + "name": "MoveToColorTemperature", + "code": 10, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "EnhancedMoveToHue", + "code": 64, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "EnhancedMoveHue", + "code": 65, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "EnhancedStepHue", + "code": 66, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "EnhancedMoveToHueAndSaturation", + "code": 67, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "ColorLoopSet", + "code": 68, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "StopMoveStep", + "code": 71, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "MoveColorTemperature", + "code": 75, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "StepColorTemperature", + "code": 76, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + } + ], + "attributes": [ + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "client", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "5", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Color Control", + "code": 768, + "mfgCode": null, + "define": "COLOR_CONTROL_CLUSTER", + "side": "server", + "enabled": 0, + "attributes": [ + { + "name": "CurrentHue", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "CurrentSaturation", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RemainingTime", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "CurrentX", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x616B", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "CurrentY", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x607D", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "DriftCompensation", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "enum8", + "included": 0, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "CompensationText", + "code": 6, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 0, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ColorTemperatureMireds", + "code": 7, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00FA", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ColorMode", + "code": 8, + "mfgCode": null, + "side": "server", + "type": "enum8", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x01", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "Options", + "code": 15, + "mfgCode": null, + "side": "server", + "type": "bitmap8", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "NumberOfPrimaries", + "code": 16, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "Primary1X", + "code": 17, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 0, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Primary1Y", + "code": 18, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 0, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Primary1Intensity", + "code": 19, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 0, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Primary2X", + "code": 21, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 0, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Primary2Y", + "code": 22, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 0, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Primary2Intensity", + "code": 23, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 0, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Primary3X", + "code": 25, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 0, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Primary3Y", + "code": 26, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 0, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Primary3Intensity", + "code": 27, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 0, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Primary4X", + "code": 32, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 0, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Primary4Y", + "code": 33, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 0, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Primary4Intensity", + "code": 34, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 0, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Primary5X", + "code": 36, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 0, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Primary5Y", + "code": 37, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 0, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Primary5Intensity", + "code": 38, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 0, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Primary6X", + "code": 40, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 0, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Primary6Y", + "code": 41, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 0, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Primary6Intensity", + "code": 42, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 0, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "WhitePointX", + "code": 48, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 0, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "WhitePointY", + "code": 49, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 0, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ColorPointRX", + "code": 50, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 0, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ColorPointRY", + "code": 51, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 0, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ColorPointRIntensity", + "code": 52, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 0, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ColorPointGX", + "code": 54, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 0, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ColorPointGY", + "code": 55, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 0, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ColorPointGIntensity", + "code": 56, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 0, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ColorPointBX", + "code": 58, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 0, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ColorPointBY", + "code": 59, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 0, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ColorPointBIntensity", + "code": 60, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 0, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EnhancedCurrentHue", + "code": 16384, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "EnhancedColorMode", + "code": 16385, + "mfgCode": null, + "side": "server", + "type": "enum8", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x01", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ColorLoopActive", + "code": 16386, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ColorLoopDirection", + "code": 16387, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ColorLoopTime", + "code": 16388, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0019", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ColorLoopStartEnhancedHue", + "code": 16389, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x2300", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ColorLoopStoredEnhancedHue", + "code": 16390, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ColorCapabilities", + "code": 16394, + "mfgCode": null, + "side": "server", + "type": "bitmap16", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ColorTempPhysicalMinMireds", + "code": 16395, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ColorTempPhysicalMaxMireds", + "code": 16396, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0xFEFF", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "CoupleColorTempToLevelMinMireds", + "code": 16397, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "StartUpColorTemperatureMireds", + "code": 16400, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 0, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 0, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 0, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x1F", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "5", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Occupancy Sensing", + "code": 1030, + "mfgCode": null, + "define": "OCCUPANCY_SENSING_CLUSTER", + "side": "client", + "enabled": 0, + "attributes": [ + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "client", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "3", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Occupancy Sensing", + "code": 1030, + "mfgCode": null, + "define": "OCCUPANCY_SENSING_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "occupancy", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "bitmap8", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "occupancy sensor type", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "enum8", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "occupancy sensor type bitmap", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "bitmap8", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "3", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + } + ] + } + ], + "endpoints": [ + { + "endpointTypeName": "MA-rootdevice", + "endpointTypeIndex": 0, + "profileId": 259, + "endpointId": 0, + "networkId": 0, + "endpointVersion": 1, + "deviceIdentifier": 22 + }, + { + "endpointTypeName": "MA-dimmablelight", + "endpointTypeIndex": 1, + "profileId": 259, + "endpointId": 1, + "networkId": 0, + "endpointVersion": 1, + "deviceIdentifier": 21 + } + ], + "log": [] +} \ No newline at end of file diff --git a/examples/contact-sensor-app/nxp/k32w/k32w0/.gn b/examples/contact-sensor-app/nxp/k32w/k32w0/.gn new file mode 100644 index 00000000000000..3d48789e30ab3d --- /dev/null +++ b/examples/contact-sensor-app/nxp/k32w/k32w0/.gn @@ -0,0 +1,28 @@ +# Copyright (c) 2020 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. + +import("//build_overrides/build.gni") + +# The location of the build configuration file. +buildconfig = "${build_root}/config/BUILDCONFIG.gn" + +# CHIP uses angle bracket includes. +check_system_includes = true + +default_args = { + target_cpu = "arm" + target_os = "freertos" + + import("//args.gni") +} diff --git a/examples/contact-sensor-app/nxp/k32w/k32w0/BUILD.gn b/examples/contact-sensor-app/nxp/k32w/k32w0/BUILD.gn new file mode 100644 index 00000000000000..8a0ace589d009a --- /dev/null +++ b/examples/contact-sensor-app/nxp/k32w/k32w0/BUILD.gn @@ -0,0 +1,143 @@ +# Copyright (c) 2021 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/chip.gni") +import("//build_overrides/k32w0_sdk.gni") +import("//build_overrides/openthread.gni") + +import("${k32w0_sdk_build_root}/k32w0_executable.gni") +import("${k32w0_sdk_build_root}/k32w0_sdk.gni") + +import("${chip_root}/src/crypto/crypto.gni") +import("${chip_root}/src/lib/core/core.gni") +import("${chip_root}/src/platform/device.gni") + +if (chip_pw_tokenizer_logging) { + import("//build_overrides/pigweed.gni") + import("$dir_pw_tokenizer/database.gni") +} + +assert(current_os == "freertos") + +k32w0_platform_dir = "${chip_root}/examples/platform/nxp/k32w/k32w0" + +k32w0_sdk("sdk") { + sources = [ + "${k32w0_platform_dir}/app/project_include/OpenThreadConfig.h", + "include/CHIPProjectConfig.h", + "include/FreeRTOSConfig.h", + "main/include/app_config.h", + ] + + public_deps = + [ "${chip_root}/third_party/openthread/platforms:libopenthread-platform" ] + + include_dirs = [ + "main/include", + "main", + "include", + "${k32w0_platform_dir}/app/project_include", + "${k32w0_platform_dir}/app/support", + "${k32w0_platform_dir}/util/include", + ] + + if (chip_with_se05x == 1) { + include_dirs += [ "${chip_root}/examples/platform/nxp/se05x" ] + } + + defines = [] + if (is_debug) { + defines += [ "BUILD_RELEASE=0" ] + } else { + defines += [ "BUILD_RELEASE=1" ] + } +} + +k32w0_executable("contact_sensor_app") { + output_name = "chip-k32w0x-contact-example" + + sources = [ + "${k32w0_platform_dir}/util/LEDWidget.cpp", + "${k32w0_platform_dir}/util/include/LEDWidget.h", + "main/AppTask.cpp", + "main/ContactSensorManager.cpp", + "main/ZclCallbacks.cpp", + "main/include/AppEvent.h", + "main/include/AppTask.h", + "main/include/ContactSensorManager.h", + "main/main.cpp", + ] + + deps = [ + ":sdk", + "${chip_root}/examples/common/QRCode", + "${chip_root}/examples/contact-sensor-app/contact-sensor-common", + "${chip_root}/examples/providers:device_info_provider", + "${chip_root}/src/lib", + "${chip_root}/third_party/mbedtls:mbedtls", + "${k32w0_platform_dir}/app/support:freertos_mbedtls_utils", + ] + + if (chip_openthread_ftd) { + deps += [ + "${chip_root}/third_party/openthread/repo:libopenthread-cli-ftd", + "${chip_root}/third_party/openthread/repo:libopenthread-ftd", + ] + } else { + deps += [ + "${chip_root}/third_party/openthread/repo:libopenthread-cli-mtd", + "${chip_root}/third_party/openthread/repo:libopenthread-mtd", + ] + } + + cflags = [ "-Wconversion" ] + + output_dir = root_out_dir + + ldscript = "${k32w0_platform_dir}/app/ldscripts/chip-k32w0x-linker.ld" + + inputs = [ ldscript ] + + ldflags = [ "-T" + rebase_path(ldscript, root_build_dir) ] + + if (chip_enable_ota_requestor) { + ldflags += [ + "-Wl,--defsym", + "-Wl,__app_load_address__=0x4000", + "-Wl,--defsym", + "-Wl,__app_stated_size__=0x99200", + "-Wl,-print-memory-usage", + ] + } +} + +if (chip_pw_tokenizer_logging) { + pw_tokenizer_database("contact_sensor_app.database") { + database = "$root_build_dir/chip-k32w0x-contact-example-database.bin" + create = "binary" + deps = [ ":contact_sensor_app" ] + optional_paths = [ "$root_build_dir/chip-k32w0x-contact-example" ] + } +} + +group("k32w0") { + deps = [ ":contact_sensor_app" ] + if (chip_pw_tokenizer_logging) { + deps += [ ":contact_sensor_app.database" ] + } +} + +group("default") { + deps = [ ":k32w0" ] +} diff --git a/examples/contact-sensor-app/nxp/k32w/k32w0/README.md b/examples/contact-sensor-app/nxp/k32w/k32w0/README.md new file mode 100644 index 00000000000000..c1633be5b1eae6 --- /dev/null +++ b/examples/contact-sensor-app/nxp/k32w/k32w0/README.md @@ -0,0 +1,592 @@ +# CHIP K32W061 Contact Sensor Example Application + +The Project CHIP K32W061 Contact Sensor Example uses buttons to test changing +the lock and device states and LEDs to show the state of these changes. You can +use this example as a reference for creating your own application. + +The example is based on +[Project CHIP](https://github.com/project-chip/connectedhomeip) and the NXP K32W +SDK, and a simulated contact sensor over a low-power, 802.15.4 Thread network. + +The example behaves as a Project CHIP accessory, that is a device that can be +paired into an existing Project CHIP network and can be controlled by this +network. + +


+ +- [CHIP K32W0 Contact Sensor Example Application](#chip-k32w-contact-example-application) - +- [Introduction](#introduction) + - [Bluetooth LE Advertising](#bluetooth-le-advertising) + - [Bluetooth LE Rendezvous](#bluetooth-le-rendezvous) +- [Device UI](#device-ui) +- [Building](#building) + - [Known issues](#building-issues) +- [Manufacturing data](#manufacturing) +- [Flashing and debugging](#flashdebug) +- [Pigweed Tokenizer](#tokenizer) + - [Detokenizer script](#detokenizer) + - [Notes](#detokenizer-notes) + - [Known issues](#detokenizer-known-issues) +- [Tinycrypt ECC operations](#tinycrypt) + - [Building steps](#tinycrypt-building-steps) +- [OTA](#ota) + - [Writing the SSBL](#ssbl) + - [Writing the PSECT](#psect) + - [Writing the application](#appwrite) + - [OTA Testing](#otatesting) + - [Known issues](#otaissues) +- [Low power](#low-power) + + - [Known issues](#low-power-issues) + + + + + +## Introduction + +![K32W061 DK6](../../../../platform/nxp/k32w/k32w0/doc/images/k32w-dk6.jpg) + +The K32W061 contact sensor example application provides a working demonstration +of a connected contact sensor device, built using the Project CHIP codebase and +the NXP K32W061 SDK. The example supports remote access (e.g.: using CHIP Tool +from a mobile phone) and control of a simulated contact sensor over a low-power, +802.15.4 Thread network. It is capable of being paired into an existing Project +CHIP network along with other Project CHIP-enabled devices. + +The example targets the +[NXP K32W061 DK6](https://www.nxp.com/products/wireless/thread/k32w061-41-high-performance-secure-and-ultra-low-power-mcu-for-zigbeethread-and-bluetooth-le-5-0-with-built-in-nfc-option:K32W061_41) +development kit, but is readily adaptable to other K32W-based hardware. + +The CHIP device that runs the contact sensor application is controlled by the +CHIP controller device over the Thread protocol. By default, the CHIP device has +Thread disabled, and it should be paired over Bluetooth LE with the CHIP +controller and obtain configuration from it. The actions required before +establishing full communication are described below. + +The example also comes with a test mode, which allows to start Thread with the +default settings by pressing a button. However, this mode does not guarantee +that the device will be able to communicate with the CHIP controller and other +devices. + +### SE051H Secure Element + +Deployment of this firmware configuration requires the K32W061 board setups +using the K32W061 module board, SE051 Expansion board and Generic Expansion +board as shown below: + +![SE051H + K32W061 DK6](../../../../platform/nxp/k32w/k32w0/doc/images/k32w-se.jpg) + +The SE051H Secure Element extension may be used for best in class security and +offloading some of the Project CHIP cryptographic operations. Depending on your +hardware configuration, choose one of the options below (building with or +without Secure Element). NOTE: the SE051H is a derivative of the SE051 product +family (see http://www.nxp.com/SE051) including dedicated CHIP support in +addition to the SE051 feature set. See the material provided separately by NXP +for more details on SE051H. + +### Bluetooth LE Advertising + +In this example, to commission the device onto a Project CHIP network, it must +be discoverable over Bluetooth LE. For security reasons, you must start +Bluetooth LE advertising manually after powering up the device by pressing +Button USERINTERFACE. + +### Bluetooth LE Rendezvous + +In this example, the commissioning procedure (called rendezvous) is done over +Bluetooth LE between a CHIP device and the CHIP controller, where the controller +has the commissioner role. + +To start the rendezvous, the controller must get the commissioning information +from the CHIP device. The data payload is encoded within a QR code, printed to +the UART console and shared using an NFC tag. For security reasons, you must +start NFC tag emulation manually after powering up the device by pressing +Button 4. + +### Thread Provisioning + +Last part of the rendezvous procedure, the provisioning operation involves +sending the Thread network credentials from the CHIP controller to the CHIP +device. As a result, device is able to join the Thread network and communicate +with other Thread devices in the network. + +## Device UI + +The example application provides a simple UI that depicts the state of the +device and offers basic user control. This UI is implemented via the +general-purpose LEDs and buttons built in to the OM15082 Expansion board +attached to the DK6 board. + +**LED D2** shows the overall state of the device and its connectivity. Four +states are depicted: + +- _Short Flash On (50ms on/950ms off)_ — The device is in an + unprovisioned (unpaired) state and is waiting for a commissioning + application to connect. + +* _Rapid Even Flashing (100ms on/100ms off)_ — The device is in an + unprovisioned state and a commissioning application is connected via BLE. + +- _Short Flash Off (950ms on/50ms off)_ — The device is full + provisioned, but does not yet have full network (Thread) or service + connectivity. + +* _Solid On_ — The device is fully provisioned and has full network and + service connectivity. + +**LED D3** shows the state of the simulated lock bolt. When the LED is lit the +bolt is extended (i.e. door locked); when not lit, the bolt is retracted (door +unlocked). The LED will flash whenever the simulated bolt is in motion from one +position to another. + +**Button SW2** can be used to reset the device to a default state. A short Press +Button SW2 initiates a factory reset. After an initial period of 3 seconds, LED2 +D2 and D3 will flash in unison to signal the pending reset. After 6 seconds will +cause the device to reset its persistent configuration and initiate a reboot. +The reset action can be cancelled by press SW2 button at any point before the 6 +second limit. + +**Button SW3** can be used to change the state of the simulated bolt. This can +be used to mimic a user manually operating the lock. The button behaves as a +toggle, swapping the state every time it is pressed. + +**Button SW4** can be used for joining a predefined Thread network advertised by +a Border Router. Default parameters for a Thread network are hard-coded and are +being used if this button is pressed. + +The remaining two LEDs (D1/D4) and button (SW1) are unused. + +Directly on the development board, **Button USERINTERFACE** can be used for +enabling Bluetooth LE advertising for a predefined period of time. Also, pushing +this button starts the NFC emulation by writing the onboarding information in +the NTAG. + +### No expansion board + +In case the **OM15082** Expansion board is not attached to the DK6 board, the +functionality of LED D2 and LED D3 is taken over by LED DS2, respectively LED +DS3, which can be found on the DK6 board. + +Also, by long pressing the **USERINTERFACE** button, the factory reset action +will be initiated. + + + +## Building + +In order to build the Project CHIP example, we recommend using a Linux +distribution (the demo-application was compiled on Ubuntu 20.04). + +- Download + [K32W0 SDK 2.6.7](https://cache.nxp.com/lgfiles/bsps/SDK_2_6_7_K32W061DK6.zip). + +- Start building the application either with Secure Element or without + + - without Secure Element + + ``` + user@ubuntu:~/Desktop/git/connectedhomeip$ export NXP_K32W0_SDK_ROOT=/home/user/Desktop/SDK_2_6_7_K32W061DK6/ + user@ubuntu:~/Desktop/git/connectedhomeip$ ./third_party/nxp/k32w0_sdk/sdk_fixes/patch_k32w_sdk.sh + user@ubuntu:~/Desktop/git/connectedhomeip$ source ./scripts/activate.sh + user@ubuntu:~/Desktop/git/connectedhomeip$ cd examples/contact-sensor-app/nxp/k32w/k32w0 + user@ubuntu:~/Desktop/git/connectedhomeip/examples/contact-sensor-app/nxp/k32w/k32w0$ gn gen out/debug --args="k32w0_sdk_root=\"${NXP_K32W0_SDK_ROOT}\" chip_with_OM15082=1 chip_with_ot_cli=0 is_debug=false chip_crypto=\"tinycrypt\" chip_with_se05x=0 chip_pw_tokenizer_logging=true mbedtls_repo=\"//third_party/connectedhomeip/third_party/nxp/libs/mbedtls\"" + user@ubuntu:~/Desktop/git/connectedhomeip/examples/contact-sensor-app/nxp/k32w/k32w0$ ninja -C out/debug + user@ubuntu:~/Desktop/git/connectedhomeip/examples/contact-sensor-app/nxp/k32w/k32w0$ $NXP_K32W0_SDK_ROOT/tools/imagetool/sign_images.sh out/debug/ + ``` + + - with Secure element Exactly the same steps as above but set + chip_with_se05x=1 in the gn command and add argument + chip_enable_ota_requestor=false + +Note that option chip_enable_ota_requestor=false are required for building with +Secure Element. These can be changed if building without Secure Element + + - for K32W041AM flavor: + Exactly the same steps as above but set build_for_k32w041am=1 in the gn command. + Also, select the K32W041AM SDK from the SDK Builder. + +Also, in case the OM15082 Expansion Board is not attached to the DK6 board, the +build argument (chip_with_OM15082) inside the gn build instruction should be set +to zero. The argument chip_with_OM15082 is set to zero by default. + +In case that Openthread CLI is needed, chip_with_ot_cli build argument must be +set to 1. + +In case signing errors are encountered when running the "sign_images.sh" script +install the recommanded packages (python version > 3, pip3, pycrypto, +pycryptodome): + +``` +user@ubuntu:~$ python3 --version +Python 3.8.2 +user@ubuntu:~$ pip3 --version +pip 20.0.2 from /usr/lib/python3/dist-packages/pip (python 3.8) +user@ubuntu:~$ pip3 list | grep -i pycrypto +pycrypto 2.6.1 +pycryptodome 3.9.8 +``` + +The resulting output file can be found in out/debug/chip-k32w0x-contact-example. + + + +## Known issues + +- When using Secure element and cross-compiling on Linux, log messages from + the Plug&Trust middleware stack may not echo to the console. + + + +## Manufacturing data + +See +[Guide for writing manufacturing data on NXP devices](../../../../platform/nxp/doc/manufacturing_flow.md). + + + +## Flashing and debugging + +Program the firmware using the official +[OpenThread Flash Instructions](https://github.com/openthread/ot-nxp/tree/main/src/k32w0/k32w061#flash-binaries). + +All you have to do is to replace the Openthread binaries from the above +documentation with _out/debug/chip-k32w0x-light-example.bin_ if DK6Programmer is +used or with _out/debug/chip-k32w0x-light-example_ if MCUXpresso is used. + + + +## Pigweed tokenizer + +The tokenizer is a pigweed module that allows hashing the strings. This greatly +reduces the flash needed for logs. The module can be enabled by building with +the gn argument _chip_pw_tokenizer_logging=true_. The detokenizer script is +needed for parsing the hashed scripts. + + + +### Detokenizer script + +The python3 script detokenizer.py is a script that decodes the tokenized logs +either from a file or from a serial port. It is located in the following path +`examples/platform/nxp/k32w/k32w0/scripts/detokenizer.py`. + +The script can be used in the following ways: + +``` +usage: detokenizer.py serial [-h] -i INPUT -d DATABASE [-o OUTPUT] +usage: detokenizer.py file [-h] -i INPUT -d DATABASE -o OUTPUT +``` + +The first parameter is either _serial_ or _file_ and it selects between decoding +from a file or from a serial port. + +The second parameter is _-i INPUT_ and it must se set to the path of the file or +the serial to decode from. + +The third parameter is _-d DATABASE_ and represents the path to the token +database to be used for decoding. The default path is +_out/debug/chip-k32w0x-contact-example-database.bin_ after a successful build. + +The forth parameter is _-o OUTPUT_ and it represents the path to the output file +where the decoded logs will be stored. This parameter is required for file usage +and optional for serial usage. If not provided when used with serial port, it +will show the decoded log only at the stdout and not save it to file. + + + +### Notes + +The token database is created automatically after building the binary if the +argument _chip_pw_tokenizer_logging=true_ was used. + +The detokenizer script must be run inside the example's folder after a +successful run of the _scripts/activate.sh_ script. The pw_tokenizer module used +by the script is loaded by the environment. An example of running the +detokenizer script to see logs of a contact-sensor app: + +``` +python3 ../../../../../examples/platform/nxp/k32w/k32w0/scripts/detokenizer.py serial -i /dev/ttyACM0 -d out/debug/chip-k32w0x-contact-example-database.bin -o device.txt +``` + + + +### Known issues + +The building process will not update the token database if it already exists. In +case that new strings are added and the database already exists in the output +folder, it must be deleted so that it will be recreated at the next build. + +Not all tokens will be decoded. This is due to a gcc/pw_tokenizer issue. The +pw_tokenizer creates special elf sections using attributes where the tokens and +strings will be stored. This sections will be used by the database creation +script. For template C++ functions, gcc ignores these attributes and places all +the strings by default in the .rodata section. As a result the database creation +script won't find them in the special-created sections. + +If run, closed and rerun with the serial option on the same serial port, the +detokenization script will get stuck and not show any logs. The solution is to +unplug and plug the board and then rerun the script. + + + +## Tinycrypt ECC operations + + + +### Building steps + +Note: This solution is temporary. + +In order to use the tinycrypt ecc operations, use the following build arguments: + +- Build without Secure element (_chip_with_se05x=0_), with tinycrypt enabled + (_chip_crypto=\"tinycrypt\"_) and with the `NXPmicro/mbedtls` library + (_mbedtls_repo=`\"//third_party/connectedhomeip/third_party/nxp/libs/mbedtls\"`_). + +To disable tinycrypt ecc operations, simply build with _chip_crypto=\"mbedtls\"_ +and with or without _mbedtls_repo_. If used with _mbedtls_repo_ the mbedtls +implementation from `NXPmicro/mbedtls` library will be used. + + + +## OTA + +The internal flash needs to be prepared for the OTA process. First 16K of the +internal flash needs to be populated with a Secondary Stage Bootloader (SSBL) +related data while the last 8.5K of flash space is holding image directory +related data (PSECT). The space between these two zones will be filled by the +application. + + + +### Writing the SSBL + +The SSBL can ge generated from one of the SDK demo examples. The SDK demo +example needs to be compiled inside MCUXpresso with the define _PDM_EXT_FLASH_. +The SSBL demo application can be imported from the _Quickstart panel_: _Import +SDK example(s)_ -> select _wireless->framework->ssbl_ application. + +![SSBL Application Select](../../../../platform/nxp/k32w/k32w0/doc/images/ssbl_select.JPG) + +The SSBL project must be compiled using the PDM_EXT_FLASH define. + +![PDM_EXT_FLASH](../../../../platform/nxp/k32w/k32w0/doc/images/pdm_ext_flash.JPG) + +Once compiled, the required ssbl file is called k32w061dk6_ssbl.bin + +![SSBL_BIN](../../../../platform/nxp/k32w/k32w0/doc/images/ssbl_bin.JPG) + +Before writing the SSBL, it it recommanded to fully erase the internal flash: + +``` +DK6Programmer.exe -V 5 -P 1000000 -s -e Flash +``` + +k32w061dk6_ssbl.bin must be written at address 0 in the internal flash: + +``` +DK6Programmer.exe -V2 -s -P 1000000 -Y -p FLASH@0x00="k32w061dk6_ssbl.bin" +``` + + + +### Writing the PSECT + +First, image directory 0 must be written: + +``` +DK6Programmer.exe -V5 -s -P 1000000 -w image_dir_0=0000000010000000 +``` + +Here is the interpretation of the fields: + +``` +00000000 -> start address 0x00000000 +1000 -> size = 0x0010 pages of 512-bytes (= 8kB) +00 -> not bootable (only used by the SSBL to support SSBL update) +00 -> SSBL Image Type +``` + +Second, image directory 1 must be written: + +``` +DK6Programmer.exe -V5 -s -P 1000000 -w image_dir_1=00400000C9040101 +``` + +Here is the interpretation of the fields: + +``` +00400000 -> start address 0x00004000 +CD04 -> 0x4C9 pages of 512-bytes (= 612,5kB) +01 -> bootable flag +01 -> image type for the application +``` + + + +### Writing the application + +DK6Programmer can be used for flashing the application: + +``` +DK6Programmer.exe -V2 -s -P 1000000 -Y -p FLASH@0x4000="chip-k32w0x-light-example.bin" +``` + +If debugging is needed, MCUXpresso can be used then for flashing the +application. Please make sure that the application is written at address 0x4000: + +![FLASH_LOCATION](../../../../platform/nxp/k32w/k32w0/doc/images/flash_location.JPG) + + + +### OTA Testing + +The OTA topology used for OTA testing is illustrated in the figure below. +Topology is similar with the one used for Matter Test Events. + +![OTA_TOPOLOGY](../../../../platform/nxp/k32w/k32w0/doc/images/ota_topology.JPG) + +The concept for OTA is the next one: + +- there is an OTA Provider Application that holds the OTA image. In our case, + this is a Linux application running on an Ubuntu based-system; +- the OTA Requestor functionality is embedded inside the Lighting Application. + It will be used for requesting OTA blocks from the OTA Provider; +- the controller (a linux application called chip-tool) will be used for + commissioning both the device and the OTA Provider App. The device will be + commissioned using the standard Matter flow (BLE + IEEE 802.15.4) while the + OTA Provider Application will be commissioned using the _onnetwork_ option + of chip-tool; +- during commissioning, each device is assigned a node id by the chip-tool + (can be specified manually by the user). Using the node id of the device and + of the lighting application, chip-tool triggers the OTA transfer by invoking + the _announce-ota-provider_ command - basically, the OTA Requestor is + informed of the node id of the OTA Provider Application. + +_Computer #1_ can be any system running an Ubuntu distribution. We recommand +using TE 7.5 instructions from +[here](https://groups.csa-iot.org/wg/matter-csg/document/24839), where RPi 4 are +proposed. Also, TE 7.5 instructions document point to the OS/Docker images that +should be used on the RPis. For compatibility reasons, we recommand compiling +chip-tool and OTA Provider applications with the same commit id that was used +for compiling the Lighting Application. Also, please note that there is a single +controller (chip-tool) running on Computer #1 which is used for commissioning +both the device and the OTA Provider Application. If needed, +[these instructions](https://itsfoss.com/connect-wifi-terminal-ubuntu/) could be +used for connecting the RPis to WiFi. + +Build the Linux OTA provider application: + +``` +user@computer1:~/connectedhomeip$ : ./scripts/examples/gn_build_example.sh examples/ota-provider-app/linux out/ota-provider-app chip_config_network_layer_ble=false +``` + +Build OTA image and start the OTA Provider Application: + +``` +user@computer1:~/connectedhomeip$ : ./src/app/ota_image_tool.py create -v 0xDEAD -p 0xBEEF -vn 1 -vs "1.0" -da sha256 chip-k32w0x-light-example.bin chip-k32w0x-light-example.ota +user@computer1:~/connectedhomeip$ : rm -rf /tmp/chip_* +user@computer1:~/connectedhomeip$ : ./out/ota-provider-app/chip-ota-provider-app -f chip-k32w0x-light-example.ota +``` + +Build Linux chip-tool: + +``` +user@computer1:~/connectedhomeip$ : ./scripts/examples/gn_build_example.sh examples/chip-tool out/chip-tool-app +``` + +Provision the OTA provider application and assign node id _1_. Also, grant ACL +entries to allow OTA requestors: + +``` +user@computer1:~/connectedhomeip$ : rm -rf /tmp/chip_* +user@computer1:~/connectedhomeip$ : ./out/chip-tool-app/chip-tool pairing onnetwork 1 20202021 +user@computer1:~/connectedhomeip$ : ./out/chip-tool-app/chip-tool accesscontrol write acl '[{"fabricIndex": 1, "privilege": 5, "authMode": 2, "subjects": [112233], "targets": null}, {"fabricIndex": 1, "privilege": 3, "authMode": 2, "subjects": null, "targets": null}]' 1 0 +``` + +Provision the device and assign node id _2_: + +``` +user@computer1:~/connectedhomeip$ : ./out/chip-tool-app/chip-tool pairing ble-thread 2 hex: 20202021 3840 +``` + +Start the OTA process: + +``` +user@computer1:~/connectedhomeip$ : ./out/chip-tool-app/chip-tool otasoftwareupdaterequestor announce-ota-provider 1 0 0 0 2 0 +``` + + + +## Known issues + +- SRP cache on the openthread border router needs to flushed each time a new + commissioning process is attempted. For this, factory reset the device, then + execute _ot-ctl server disable_ followed by _ot-ctl server enable_. After + this step, the commissioning process of the device can start; +- Due to some MDNS issues, the commissioning of the OTA Provider Application + may fail. Please make sure that the SRP cache is disabled (_ot-ctl srp + server disable_) on the openthread border router while commissioning the OTA + Provider Application; +- No other Docker image should be running (e.g.: Docker image needed by Test + Harness) except the OTBR one. A docker image can be killed using the + command: + +``` +user@computer1:~/connectedhomeip$ : sudo docker kill $container_id +``` + +- In order to avoid MDNS issues, only one interface should be active at one + time. E.g.: if WiFi is used then disable the Ethernet interface and also + disable multicast on that interface: + +``` +user@computer1:~/connectedhomeip$ sudo ip link set dev eth0 down +user@computer1:~/connectedhomeip$ sudo ifconfig eth0 -multicast +``` + +- If OTBR Docker image is used, then the "-B" parameter should point to the + interface used for the backbone. + +- If Wi-Fi is used on a RPI4, then a 5Ghz network should be selected. + Otherwise, issues related to BLE-WiFi combo may appear. + + + +## Low power + +The example also offers the possibility to run in low power mode. This means +that the board will go in a deep power down mode most of the time and the power +consumption will be very low. + +In order build with low power support, the _chip_with_low_power=1_ must be +provided to the build system. In this case, please note that the GN build +arguments chip*with_OM15082 and \_chip_with_ot_cli* must be set to 0. + +In order to maintain a low power consumption, the LEDs showing the state of the +elock and the internal state are disabled. Console logs can be used instead. +Also, please note that once the board is flashed with MCUXpresso the debugger +disconnects because the board enters low power. + +Power Measurement Tool can be used inside MCUXpresso for checking the power +consumption pattern: Window -> Show View -> Other -> Power Measurement Tool. The +configuration for this tool is the next one: + +![POWER_CONF](../../../../platform/nxp/k32w/k32w0/doc/images/power_conf.JPG) + +Also, please make sure that the J14 jumper is set to the _ENABLED_ position and +no expansion board is attached to the DK6. A view from this tool is illustrated +below: + +![POWER_VIEW](../../../../platform/nxp/k32w/k32w0/doc/images/power_view.JPG) + +Please note that that the Power Measurement Tool is not very accurate and +professional tools must be used if exact power consumption needs to be known. + + + +## Known issues + +- Power Measurement Tool may not work correctly in MCUXpresso versions greater + that 11.0.1. diff --git a/examples/contact-sensor-app/nxp/k32w/k32w0/args.gni b/examples/contact-sensor-app/nxp/k32w/k32w0/args.gni new file mode 100644 index 00000000000000..5f4766d8429e64 --- /dev/null +++ b/examples/contact-sensor-app/nxp/k32w/k32w0/args.gni @@ -0,0 +1,23 @@ +# Copyright (c) 2020 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. + +import("//build_overrides/chip.gni") +import("${chip_root}/examples/platform/nxp/k32w/k32w0/args.gni") + +# SDK target. This is overridden to add our SDK app_config.h & defines. +k32w0_sdk_target = get_label_info(":sdk", "label_no_toolchain") + +chip_enable_ota_requestor = true +chip_stack_lock_tracking = "fatal" +chip_enable_ble = true diff --git a/examples/contact-sensor-app/nxp/k32w/k32w0/build_overrides b/examples/contact-sensor-app/nxp/k32w/k32w0/build_overrides new file mode 120000 index 00000000000000..ad07557834803a --- /dev/null +++ b/examples/contact-sensor-app/nxp/k32w/k32w0/build_overrides @@ -0,0 +1 @@ +../../../../build_overrides/ \ No newline at end of file diff --git a/examples/contact-sensor-app/nxp/k32w/k32w0/include/CHIPProjectConfig.h b/examples/contact-sensor-app/nxp/k32w/k32w0/include/CHIPProjectConfig.h new file mode 100644 index 00000000000000..101f959f6d5c72 --- /dev/null +++ b/examples/contact-sensor-app/nxp/k32w/k32w0/include/CHIPProjectConfig.h @@ -0,0 +1,231 @@ +/* + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2020 Google LLC. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Example project configuration file for CHIP. + * + * This is a place to put application or project-specific overrides + * to the default configuration values for general CHIP features. + * + */ + +#pragma once + +// Security and Authentication disabled for development build. +// For convenience, enable CHIP Security Test Mode and disable the requirement for +// authentication in various protocols. +// WARNING: These options make it possible to circumvent basic CHIP security functionality, +// including message encryption. Because of this they MUST NEVER BE ENABLED IN PRODUCTION BUILDS. +#define CHIP_CONFIG_SECURITY_TEST_MODE 0 + +// Use hard-coded test certificates already embedded in generic chip code => set it to 0 +// Use real/development certificates => set it to 1 + file the provisioning section from +// the internal flash +#ifndef CONFIG_CHIP_K32W0_REAL_FACTORY_DATA +#define CONFIG_CHIP_K32W0_REAL_FACTORY_DATA 0 +#endif + +#if CONFIG_CHIP_K32W0_REAL_FACTORY_DATA + +// VID/PID for product => will be used by Basic Information Cluster +#define CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID 0x1037 +#define CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID 0xA220 + +// set it to 0 for the moment +#define CHIP_DEVICE_CONFIG_ENABLE_DEVICE_INSTANCE_INFO_PROVIDER 0 + +#ifndef CHIP_DEVICE_CONFIG_CERTIFICATION_DECLARATION +//-> format_version = 1 +//-> vendor_id = 0x1037 +//-> product_id_array = [ 0xA220 ] +//-> device_type_id = 0x0015 +//-> certificate_id = "ZIG20142ZB330003-24" +//-> security_level = 0 +//-> security_information = 0 +//-> version_number = 0x2694 +//-> certification_type = 1 +//-> dac_origin_vendor_id is not present +//-> dac_origin_product_id is not present +#define CHIP_DEVICE_CONFIG_CERTIFICATION_DECLARATION \ + { \ + 0x30, 0x81, 0xe7, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x81, 0xd9, 0x30, 0x81, 0xd6, \ + 0x02, 0x01, 0x03, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x30, \ + 0x43, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x36, 0x04, 0x34, 0x15, 0x24, 0x00, \ + 0x01, 0x25, 0x01, 0x37, 0x10, 0x36, 0x02, 0x05, 0x20, 0xa2, 0x18, 0x24, 0x03, 0x15, 0x2c, 0x04, 0x13, 0x5a, 0x49, \ + 0x47, 0x32, 0x30, 0x31, 0x34, 0x31, 0x5a, 0x42, 0x33, 0x33, 0x30, 0x30, 0x30, 0x31, 0x2d, 0x32, 0x34, 0x24, 0x05, \ + 0x00, 0x24, 0x06, 0x00, 0x24, 0x07, 0x01, 0x24, 0x08, 0x01, 0x18, 0x31, 0x7d, 0x30, 0x7b, 0x02, 0x01, 0x03, 0x80, \ + 0x14, 0x62, 0xfa, 0x82, 0x33, 0x59, 0xac, 0xfa, 0xa9, 0x96, 0x3e, 0x1c, 0xfa, 0x14, 0x0a, 0xdd, 0xf5, 0x04, 0xf3, \ + 0x71, 0x60, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x30, 0x0a, 0x06, 0x08, \ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x04, 0x47, 0x30, 0x45, 0x02, 0x20, 0x11, 0x8c, 0x13, 0x63, 0x9a, \ + 0xe7, 0x77, 0xaa, 0xc1, 0x52, 0x8c, 0x46, 0x40, 0x82, 0xcc, 0xdb, 0x6c, 0x43, 0x4d, 0xfc, 0xff, 0xe2, 0x5e, 0x1f, \ + 0xda, 0xef, 0xdf, 0x0d, 0xf1, 0x7c, 0x2c, 0xcd, 0x02, 0x21, 0x00, 0xbf, 0xad, 0x91, 0xc3, 0x3b, 0xf5, 0xb9, 0x89, \ + 0x2e, 0x5e, 0x15, 0x3c, 0x52, 0x61, 0xad, 0xb8, 0x53, 0x42, 0x46, 0xc6, 0x7d, 0xec, 0xc0, 0x93, 0x10, 0x1f, 0xc4, \ + 0xd2, 0xc3, 0x8a, 0xd5, 0x16, \ + } + +// All remaining data will be pulled from the provisioning region of flash. +#endif + +#else + +// Use a default setup PIN code if one hasn't been provisioned in flash. +#define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE 20202021 +#define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR 0xF00 + +// Use a default pairing code if one hasn't been provisioned in flash. +#define CHIP_DEVICE_CONFIG_USE_TEST_PAIRING_CODE "CHIPUS" + +/** + * CHIP_DEVICE_CONFIG_TEST_SERIAL_NUMBER + * + * Enables the use of a hard-coded default serial number if none + * is found in CHIP NV storage. + */ +#define CHIP_DEVICE_CONFIG_TEST_SERIAL_NUMBER "TEST_SN" + +/** + * CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID + * + * 0xFFF1: Test vendor. + */ +#define CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID 0xFFF1 + +/** + * CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID + * + */ +#define CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID 0x8006 + +#endif + +/** + * CHIP_DEVICE_CONFIG_DEVICE_HARDWARE_VERSION + * + * The hardware version number assigned to device or product by the device vendor. This + * number is scoped to the device product id, and typically corresponds to a revision of the + * physical device, a change to its packaging, and/or a change to its marketing presentation. + * This value is generally *not* incremented for device software versions. + */ +#define CHIP_DEVICE_CONFIG_DEVICE_HARDWARE_VERSION 100 + +#ifndef CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION_STRING +#define CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION_STRING "v0.1.0" +#endif + +/** + * CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING + * + * A string identifying the software version running on the device. + * CHIP currently expects the software version to be in the format + * {MAJOR_VERSION}.0d{MINOR_VERSION} + */ +#ifndef CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING +#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING "03-2022-te8" +#endif + +#ifndef CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION +#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION 42020 +#endif + +#ifndef CHIP_DEVICE_CONFIG_DEVICE_VENDOR_NAME +#define CHIP_DEVICE_CONFIG_DEVICE_VENDOR_NAME "NXP Semiconductors" +#endif + +#ifndef CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_NAME +#define CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_NAME "NXP Demo App" +#endif + +/** + * CHIP_DEVICE_CONFIG_ENABLE_CHIP_TIME_SERVICE_TIME_SYNC + * + * Enables synchronizing the device's real time clock with a remote CHIP Time service + * using the CHIP Time Sync protocol. + */ +// #define CHIP_DEVICE_CONFIG_ENABLE_CHIP_TIME_SERVICE_TIME_SYNC 1 + +/** + * CHIP_DEVICE_CONFIG_BLE_FAST_ADVERTISING_TIMEOUT + * + * The amount of time in miliseconds after which BLE should change his advertisements + * from fast interval to slow interval. + * + * 30000 (30 secondes). + */ +#define CHIP_DEVICE_CONFIG_BLE_FAST_ADVERTISING_TIMEOUT (30 * 1000) + +/** + * CHIP_DEVICE_CONFIG_BLE_ADVERTISING_TIMEOUT + * + * The amount of time in miliseconds after which BLE advertisement should be disabled, counting + * from the moment of slow advertisement commencement. + * + * Defaults to 9000000 (15 minutes). + */ +#define CHIP_DEVICE_CONFIG_BLE_ADVERTISING_TIMEOUT (15 * 60 * 1000) + +/** + * @def CHIP_CONFIG_MAX_FABRICS + * + * @brief + * Maximum number of fabrics the device can participate in. Each fabric can + * provision the device with its unique operational credentials and manage + * its own access control lists. + */ +#define CHIP_CONFIG_MAX_FABRICS 5 // 5 is the minimum number of supported fabrics + +#define CHIP_DEVICE_CONFIG_ENABLE_SED 1 +#define CHIP_DEVICE_CONFIG_SED_IDLE_INTERVAL 1000_ms32 +#define CHIP_DEVICE_CONFIG_SED_ACTIVE_INTERVAL 100_ms32 +/** + * @def CHIP_IM_MAX_NUM_COMMAND_HANDLER + * + * @brief Defines the maximum number of CommandHandler, limits the number of active commands transactions on server. + */ +#define CHIP_IM_MAX_NUM_COMMAND_HANDLER 2 + +/** + * @def CHIP_IM_MAX_NUM_WRITE_HANDLER + * + * @brief Defines the maximum number of WriteHandler, limits the number of active write transactions on server. + */ +#define CHIP_IM_MAX_NUM_WRITE_HANDLER 2 + +/** + * CHIP_CONFIG_EVENT_LOGGING_DEFAULT_IMPORTANCE + * + * For a development build, set the default importance of events to be logged as Debug. + * Since debug is the lowest importance level, this means all standard, critical, info and + * debug importance level vi events get logged. + */ +#if BUILD_RELEASE +#define CHIP_CONFIG_EVENT_LOGGING_DEFAULT_IMPORTANCE chip::Profiles::DataManagement::Production +#else +#define CHIP_CONFIG_EVENT_LOGGING_DEFAULT_IMPORTANCE chip::Profiles::DataManagement::Debug +#endif // BUILD_RELEASE + +#define CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY 1 + +/** + * CHIP_DEVICE_CONFIG_INIT_OTA_DELAY + * + * The amount of time in miliseconds after which OTA initialization should be + * scheduled after a new image is applied. + * + */ +#define CHIP_DEVICE_CONFIG_INIT_OTA_DELAY 3000 diff --git a/examples/contact-sensor-app/nxp/k32w/k32w0/include/FreeRTOSConfig.h b/examples/contact-sensor-app/nxp/k32w/k32w0/include/FreeRTOSConfig.h new file mode 100644 index 00000000000000..aaf62544a61edb --- /dev/null +++ b/examples/contact-sensor-app/nxp/k32w/k32w0/include/FreeRTOSConfig.h @@ -0,0 +1,187 @@ +/* + * FreeRTOS Kernel V10.2.0 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +#pragma once + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + * + * See http://www.freertos.org/a00110.html. + *----------------------------------------------------------*/ + +#define configUSE_PREEMPTION 1 + +#if defined(cPWR_UsePowerDownMode) && (cPWR_UsePowerDownMode) +#define configUSE_TICKLESS_IDLE 1 +#else +#define configUSE_TICKLESS_IDLE 0 +#endif + +#define configCPU_CLOCK_HZ (SystemCoreClock) +#define configTICK_RATE_HZ ((TickType_t) 100) +#define configMAX_PRIORITIES (8) + +#if defined(cPWR_UsePowerDownMode) && (cPWR_UsePowerDownMode) +#define configMINIMAL_STACK_SIZE ((unsigned short) 610) +#else +#define configMINIMAL_STACK_SIZE ((unsigned short) 450) +#endif + +#define configMAX_TASK_NAME_LEN 20 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 1 +#define configUSE_TASK_NOTIFICATIONS 1 +#define configUSE_MUTEXES 1 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configUSE_COUNTING_SEMAPHORES 1 +#define configUSE_ALTERNATIVE_API 0 /* Deprecated! */ +#define configQUEUE_REGISTRY_SIZE 8 +#define configUSE_QUEUE_SETS 0 +/* make sure that Thread task can interrupt lengthy Matter + * processing in case priority inversion occurs + */ +#define configUSE_TIME_SLICING 1 +#define configUSE_NEWLIB_REENTRANT 0 +#define configENABLE_BACKWARD_COMPATIBILITY 1 +#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 5 + +/* Tasks.c additions (e.g. Thread Aware Debug capability) */ +#define configINCLUDE_FREERTOS_TASK_C_ADDITIONS_H 1 + +/* Used memory allocation (heap_x.c) */ +#define configFRTOS_MEMORY_SCHEME 4 + +/* Memory allocation related definitions. */ +#define configSUPPORT_STATIC_ALLOCATION 0 +#define configSUPPORT_DYNAMIC_ALLOCATION 1 +#define configTOTAL_HEAP_SIZE ((size_t)(gTotalHeapSize_c)) +#define configAPPLICATION_ALLOCATED_HEAP 1 + +/* Hook function related definitions. */ +#ifndef configUSE_IDLE_HOOK +#define configUSE_IDLE_HOOK 1 +#endif +#define configUSE_TICK_HOOK 0 +#define configCHECK_FOR_STACK_OVERFLOW 0 +#ifndef configUSE_MALLOC_FAILED_HOOK +#define configUSE_MALLOC_FAILED_HOOK 0 +#endif +#define configUSE_DAEMON_TASK_STARTUP_HOOK 0 + +/* Run time and task stats gathering related definitions. */ +#define configGENERATE_RUN_TIME_STATS 0 +#define configUSE_TRACE_FACILITY 1 +#define configUSE_STATS_FORMATTING_FUNCTIONS 0 + +/* Task aware debugging. */ +#define configRECORD_STACK_HIGH_ADDRESS 1 + +/* Co-routine related definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES 2 + +/* Software timer related definitions. */ +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES - 1) +#define configTIMER_QUEUE_LENGTH 10 +#define configTIMER_TASK_STACK_DEPTH (360) + +/* Define to trap errors during development. */ +#if defined gLoggingActive_d && (gLoggingActive_d != 0) +#include "dbg_logging.h" +#define configASSERT(x) \ + if ((x) == 0) \ + { \ + taskDISABLE_INTERRUPTS(); \ + DbgLogDump(1); \ + } +#else +#define configASSERT(x) \ + if ((x) == 0) \ + { \ + taskDISABLE_INTERRUPTS(); \ + for (;;) \ + ; \ + } +#endif + +/* Optional functions - most linkers will remove unused functions anyway. */ +#define INCLUDE_vTaskPrioritySet 1 +#define INCLUDE_uxTaskPriorityGet 1 +#define INCLUDE_vTaskDelete 1 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_xResumeFromISR 1 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_xTaskGetSchedulerState 1 +#define INCLUDE_xTaskGetCurrentTaskHandle 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 1 +#define INCLUDE_xTaskGetIdleTaskHandle 0 +#define INCLUDE_eTaskGetState 0 +#define INCLUDE_xEventGroupSetBitFromISR 1 +#define INCLUDE_xTimerPendFunctionCall 1 +#define INCLUDE_xTaskAbortDelay 0 +#define INCLUDE_xTaskGetHandle 0 +#define INCLUDE_xTaskResumeFromISR 1 +#define INCLUDE_xQueueGetMutexHolder 1 + +/* Interrupt nesting behaviour configuration. Cortex-M specific. */ +#ifdef __NVIC_PRIO_BITS +/* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */ +#define configPRIO_BITS __NVIC_PRIO_BITS +#else +#define configPRIO_BITS 3 +#endif + +/* The lowest interrupt priority that can be used in a call to a "set priority" +function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 0x7 + +/* The highest interrupt priority that can be used by any interrupt service +routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL +INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER +PRIORITY THAN THIS! (higher priorities are lower numeric values. */ +#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 1 + +/* Interrupt priorities used by the kernel port layer itself. These are generic +to all Cortex-M ports, and do not rely on any particular library functions. */ +#define configKERNEL_INTERRUPT_PRIORITY (configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS)) +/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!! +See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */ +#define configMAX_SYSCALL_INTERRUPT_PRIORITY (configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS)) + +/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS +standard names. */ +#define vPortSVCHandler SVC_Handler +#define xPortPendSVHandler PendSV_Handler +#define xPortSysTickHandler SysTick_Handler diff --git a/examples/contact-sensor-app/nxp/k32w/k32w0/main/AppTask.cpp b/examples/contact-sensor-app/nxp/k32w/k32w0/main/AppTask.cpp new file mode 100644 index 00000000000000..437573fc215cf1 --- /dev/null +++ b/examples/contact-sensor-app/nxp/k32w/k32w0/main/AppTask.cpp @@ -0,0 +1,888 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * Copyright (c) 2022 Google LLC. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "AppTask.h" +#include "AppEvent.h" +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +/* OTA related includes */ +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR +#include "OTAImageProcessorImpl.h" +#include "OtaSupport.h" +#include +#include +#include +#include +#endif + +#include "Keyboard.h" +#include "LED.h" +#include "LEDWidget.h" +#include "PWR_Interface.h" +#include "app_config.h" + +#if CHIP_CRYPTO_HSM +#include +#endif +#ifdef ENABLE_HSM_DEVICE_ATTESTATION +#include "DeviceAttestationSe05xCredsExample.h" +#endif + +#define FACTORY_RESET_TRIGGER_TIMEOUT 6000 +#define APP_EVENT_QUEUE_SIZE 10 + +TimerHandle_t sFunctionTimer; // FreeRTOS app sw timer. + +static QueueHandle_t sAppEventQueue; + +#if !cPWR_UsePowerDownMode +static LEDWidget sStatusLED; +static LEDWidget sContactSensorLED; +#endif + +static bool sIsThreadProvisioned = false; +static bool sHaveBLEConnections = false; +static bool sIsDnssdPlatformInitialized = false; + +static uint32_t eventMask = 0; + +#if CHIP_DEVICE_CONFIG_THREAD_ENABLE_CLI +extern "C" void K32WUartProcess(void); +#endif + +using namespace ::chip::Credentials; +using namespace ::chip::DeviceLayer; +using namespace chip; + +AppTask AppTask::sAppTask; + +static Identify gIdentify = { chip::EndpointId{ 1 }, AppTask::OnIdentifyStart, AppTask::OnIdentifyStop, + EMBER_ZCL_IDENTIFY_IDENTIFY_TYPE_VISIBLE_LED }; + +/* OTA related variables */ +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR +static DefaultOTARequestor gRequestorCore; +static DefaultOTARequestorStorage gRequestorStorage; +static DeviceLayer::DefaultOTARequestorDriver gRequestorUser; +static BDXDownloader gDownloader; +static OTAImageProcessorImpl gImageProcessor; + +constexpr uint16_t requestedOtaBlockSize = 1024; +#endif + +CHIP_ERROR AppTask::StartAppTask() +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + sAppEventQueue = xQueueCreate(APP_EVENT_QUEUE_SIZE, sizeof(AppEvent)); + if (sAppEventQueue == NULL) + { + err = APP_ERROR_EVENT_QUEUE_FAILED; + K32W_LOG("Failed to allocate app event queue"); + assert(err == CHIP_NO_ERROR); + } + + return err; +} + +CHIP_ERROR AppTask::Init() +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + if (ContactSensorMgr().Init() != 0) + { + K32W_LOG("ContactSensorMgr().Init() failed"); + assert(status == 0); + } + + PlatformMgr().AddEventHandler(MatterEventHandler, 0); + + // Init ZCL Data Model and start server + PlatformMgr().ScheduleWork(InitServer, 0); + +// Initialize device attestation config +#if CONFIG_CHIP_K32W0_REAL_FACTORY_DATA + // Initialize factory data provider + ReturnErrorOnFailure(K32W0FactoryDataProvider::GetDefaultInstance().Init()); +#if CHIP_DEVICE_CONFIG_ENABLE_DEVICE_INSTANCE_INFO_PROVIDER + SetDeviceInstanceInfoProvider(&K32W0FactoryDataProvider::GetDefaultInstance()); +#endif + SetDeviceAttestationCredentialsProvider(&K32W0FactoryDataProvider::GetDefaultInstance()); + SetCommissionableDataProvider(&K32W0FactoryDataProvider::GetDefaultInstance()); +#else +#ifdef ENABLE_HSM_DEVICE_ATTESTATION + SetDeviceAttestationCredentialsProvider(Examples::GetExampleSe05xDACProvider()); +#else + SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); +#endif + + // QR code will be used with CHIP Tool + PrintOnboardingCodes(chip::RendezvousInformationFlags(chip::RendezvousInformationFlag::kBLE)); +#endif + + /* HW init leds */ +#if !cPWR_UsePowerDownMode + LED_Init(); + + /* start with all LEDS turnedd off */ + sStatusLED.Init(SYSTEM_STATE_LED); + + sContactSensorLED.Init(CONTACT_SENSOR_STATE_LED); + sContactSensorLED.Set(ContactSensorMgr().IsContactClosed()); +#endif + UpdateDeviceState(); + + /* intialize the Keyboard and button press callback */ + KBD_Init(KBD_Callback); + + // Create FreeRTOS sw timer for Function Selection. + sFunctionTimer = xTimerCreate("FnTmr", // Just a text name, not used by the RTOS kernel + 1, // == default timer period (mS) + false, // no timer reload (==one-shot) + (void *) this, // init timer id = app task obj context + TimerEventHandler // timer callback handler + ); + if (sFunctionTimer == NULL) + { + err = APP_ERROR_CREATE_TIMER_FAILED; + K32W_LOG("app_timer_create() failed"); + assert(err == CHIP_NO_ERROR); + } + + ContactSensorMgr().SetCallback(OnStateChanged); + + // Print the current software version + char currentSoftwareVer[ConfigurationManager::kMaxSoftwareVersionStringLength + 1] = { 0 }; + err = ConfigurationMgr().GetSoftwareVersionString(currentSoftwareVer, sizeof(currentSoftwareVer)); + if (err != CHIP_NO_ERROR) + { + K32W_LOG("Get version error"); + assert(err == CHIP_NO_ERROR); + } + + K32W_LOG("Current Software Version: %s", currentSoftwareVer); + +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR + if (gImageProcessor.IsFirstImageRun()) + { + // If DNS-SD initialization was captured by MatterEventHandler, then + // OTA initialization will be started as soon as possible. Otherwise, + // a periodic timer is started until the DNS-SD initialization event + // is received. Configurable delay: CHIP_DEVICE_CONFIG_INIT_OTA_DELAY + AppTask::OnScheduleInitOTA(nullptr, nullptr); + } + else + { + PlatformMgr().ScheduleWork(AppTask::InitOTA, 0); + } +#endif + return err; +} + +void LockOpenThreadTask(void) +{ + PWR_DisallowDeviceToSleep(); + chip::DeviceLayer::ThreadStackMgr().LockThreadStack(); +} + +void UnlockOpenThreadTask(void) +{ + chip::DeviceLayer::ThreadStackMgr().UnlockThreadStack(); + PWR_AllowDeviceToSleep(); +} + +void AppTask::InitServer(intptr_t arg) +{ + static chip::CommonCaseDeviceServerInitParams initParams; + (void) initParams.InitializeStaticResourcesBeforeServerInit(); + + auto & infoProvider = chip::DeviceLayer::DeviceInfoProviderImpl::GetDefaultInstance(); + infoProvider.SetStorageDelegate(initParams.persistentStorageDelegate); + chip::DeviceLayer::SetDeviceInfoProvider(&infoProvider); + + // Init ZCL Data Model and start server + chip::Inet::EndPointStateOpenThread::OpenThreadEndpointInitParam nativeParams; + nativeParams.lockCb = LockOpenThreadTask; + nativeParams.unlockCb = UnlockOpenThreadTask; + nativeParams.openThreadInstancePtr = chip::DeviceLayer::ThreadStackMgrImpl().OTInstance(); + initParams.endpointNativeParams = static_cast(&nativeParams); + VerifyOrDie((chip::Server::GetInstance().Init(initParams)) == CHIP_NO_ERROR); +} + +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR +void AppTask::InitOTA(intptr_t arg) +{ + // Initialize and interconnect the Requestor and Image Processor objects -- START + SetRequestorInstance(&gRequestorCore); + + gRequestorStorage.Init(chip::Server::GetInstance().GetPersistentStorage()); + gRequestorCore.Init(chip::Server::GetInstance(), gRequestorStorage, gRequestorUser, gDownloader); + gRequestorUser.SetMaxDownloadBlockSize(requestedOtaBlockSize); + gRequestorUser.Init(&gRequestorCore, &gImageProcessor); + gImageProcessor.SetOTADownloader(&gDownloader); + + // Connect the gDownloader and Image Processor objects + gDownloader.SetImageProcessorDelegate(&gImageProcessor); + // Initialize and interconnect the Requestor and Image Processor objects -- END +} +#endif + +void AppTask::AppTaskMain(void * pvParameter) +{ + AppEvent event; + + CHIP_ERROR err = sAppTask.Init(); + if (err != CHIP_NO_ERROR) + { + K32W_LOG("AppTask.Init() failed"); + assert(err == CHIP_NO_ERROR); + } + + while (true) + { + TickType_t xTicksToWait = pdMS_TO_TICKS(10); + +#if defined(cPWR_UsePowerDownMode) && (cPWR_UsePowerDownMode) + xTicksToWait = portMAX_DELAY; +#endif + + BaseType_t eventReceived = xQueueReceive(sAppEventQueue, &event, xTicksToWait); + while (eventReceived == pdTRUE) + { + sAppTask.DispatchEvent(&event); + eventReceived = xQueueReceive(sAppEventQueue, &event, 0); + } + + // Collect connectivity and configuration state from the CHIP stack. Because the + // CHIP event loop is being run in a separate task, the stack must be locked + // while these values are queried. However we use a non-blocking lock request + // (TryLockChipStack()) to avoid blocking other UI activities when the CHIP + // task is busy (e.g. with a long crypto operation). + if (PlatformMgr().TryLockChipStack()) + { +#if CHIP_DEVICE_CONFIG_THREAD_ENABLE_CLI + K32WUartProcess(); +#endif + sHaveBLEConnections = (ConnectivityMgr().NumBLEConnections() != 0); + PlatformMgr().UnlockChipStack(); + } + + // Update the status LED if factory reset or identify process have not been initiated. + // + // If system has "full connectivity", keep the LED On constantly. + // + // If thread and service provisioned, but not attached to the thread network yet OR no + // connectivity to the service OR subscriptions are not fully established + // THEN blink the LED Off for a short period of time. + // + // If the system has ble connection(s) uptill the stage above, THEN blink the LEDs at an even + // rate of 100ms. + // + // Otherwise, blink the LED ON for a very short time. + +#if !cPWR_UsePowerDownMode + if (sAppTask.mFunction != Function::kFactoryReset && sAppTask.mFunction != Function::kIdentify) + { + if (sIsThreadProvisioned) + { + sStatusLED.Blink(950, 50); + } + else if (sHaveBLEConnections) + { + sStatusLED.Blink(100, 100); + } + else + { + sStatusLED.Blink(50, 950); + } + } + + sStatusLED.Animate(); + sContactSensorLED.Animate(); +#endif + } +} + +void AppTask::ButtonEventHandler(uint8_t pin_no, uint8_t button_action) +{ + if ((pin_no != RESET_BUTTON) && (pin_no != CONTACT_SENSOR_BUTTON) && (pin_no != OTA_BUTTON) && (pin_no != BLE_BUTTON)) + { + return; + } + + AppEvent button_event; + button_event.Type = AppEvent::kButton; + button_event.ButtonEvent.PinNo = pin_no; + button_event.ButtonEvent.Action = button_action; + + if (pin_no == RESET_BUTTON) + { + button_event.Handler = ResetActionEventHandler; + } + else if (pin_no == CONTACT_SENSOR_BUTTON) + { + button_event.Handler = ContactActionEventHandler; + } + else if (pin_no == OTA_BUTTON) + { + button_event.Handler = OTAHandler; + } + else if (pin_no == BLE_BUTTON) + { + button_event.Handler = BleHandler; +#if !(defined OM15082) + if (button_action == RESET_BUTTON_PUSH) + { + button_event.Handler = ResetActionEventHandler; + } +#endif + } + + sAppTask.PostEvent(&button_event); +} + +void AppTask::KBD_Callback(uint8_t events) +{ + eventMask = eventMask | (uint32_t)(1 << events); + + HandleKeyboard(); +} + +void AppTask::HandleKeyboard(void) +{ + uint8_t keyEvent = 0xFF; + uint8_t pos = 0; + + while (eventMask) + { + for (pos = 0; pos < (8 * sizeof(eventMask)); pos++) + { + if (eventMask & (1 << pos)) + { + keyEvent = pos; + eventMask = eventMask & ~(1 << pos); + break; + } + } + + switch (keyEvent) + { + case gKBD_EventPB1_c: + K32W_LOG("pb1 short press"); + +#if (defined OM15082) + ButtonEventHandler(RESET_BUTTON, RESET_BUTTON_PUSH); + break; +#else + ButtonEventHandler(BLE_BUTTON, BLE_BUTTON_PUSH); + break; +#endif + case gKBD_EventPB2_c: + ButtonEventHandler(CONTACT_SENSOR_BUTTON, CONTACT_SENSOR_BUTTON_PUSH); + break; + case gKBD_EventPB3_c: + ButtonEventHandler(OTA_BUTTON, OTA_BUTTON_PUSH); + break; + case gKBD_EventPB4_c: + ButtonEventHandler(BLE_BUTTON, BLE_BUTTON_PUSH); + break; +#if !(defined OM15082) + case gKBD_EventLongPB1_c: + K32W_LOG("pb1 long press"); + ButtonEventHandler(BLE_BUTTON, RESET_BUTTON_PUSH); + break; +#endif + default: + break; + } + } +} + +void AppTask::TimerEventHandler(TimerHandle_t xTimer) +{ + AppEvent event; + event.Type = AppEvent::kTimer; + event.TimerEvent.Context = (void *) xTimer; + event.Handler = FunctionTimerEventHandler; + sAppTask.PostEvent(&event); +} + +void AppTask::FunctionTimerEventHandler(void * aGenericEvent) +{ + AppEvent * aEvent = (AppEvent *) aGenericEvent; + + if (aEvent->Type != AppEvent::kTimer) + return; + + K32W_LOG("Device will factory reset..."); + + // Actually trigger Factory Reset + chip::Server::GetInstance().ScheduleFactoryReset(); +} + +void AppTask::ResetActionEventHandler(void * aGenericEvent) +{ + AppEvent * aEvent = (AppEvent *) aGenericEvent; + + if (aEvent->ButtonEvent.PinNo != RESET_BUTTON && aEvent->ButtonEvent.PinNo != BLE_BUTTON) + return; + + if (sAppTask.mResetTimerActive) + { + sAppTask.CancelTimer(); + sAppTask.mFunction = Function::kNoneSelected; + +#if !cPWR_UsePowerDownMode + /* restore initial state for the LED indicating contact state */ + if (!ContactSensorMgr().IsContactClosed()) + { + sContactSensorLED.Set(false); + } + else + { + sContactSensorLED.Set(true); + } +#endif + + K32W_LOG("Factory Reset was cancelled!"); + } + else + { + uint32_t resetTimeout = FACTORY_RESET_TRIGGER_TIMEOUT; + + if (sAppTask.mFunction != Function::kNoneSelected) + { + K32W_LOG("Another function is scheduled. Could not initiate Factory Reset!"); + return; + } + + K32W_LOG("Factory Reset Triggered. Push the RESET button within %lu ms to cancel!", resetTimeout); + sAppTask.mFunction = Function::kFactoryReset; + + /* LEDs will start blinking to signal that a Factory Reset was scheduled */ +#if !cPWR_UsePowerDownMode + sStatusLED.Set(false); + sContactSensorLED.Set(false); + + sStatusLED.Blink(500); + sContactSensorLED.Blink(500); +#endif + + sAppTask.StartTimer(FACTORY_RESET_TRIGGER_TIMEOUT); + } +} + +void AppTask::ContactActionEventHandler(void * aGenericEvent) +{ + AppEvent * aEvent = (AppEvent *) aGenericEvent; + ContactSensorManager::Action action = ContactSensorManager::Action::kInvalid; + CHIP_ERROR err = CHIP_NO_ERROR; + bool state_changed = false; + + if (sAppTask.mFunction != Function::kNoneSelected) + { + K32W_LOG("Another function is scheduled. Could not change contact state."); + return; + } + + if (aEvent->Type == AppEvent::kContact) + { + action = static_cast(aEvent->ContactEvent.Action); + } + else if (aEvent->Type == AppEvent::kButton) + { + if (ContactSensorMgr().IsContactClosed()) + { + action = ContactSensorManager::Action::kSignalLost; + } + else + { + action = ContactSensorManager::Action::kSignalDetected; + } + + sAppTask.SetSyncClusterToButtonAction(true); + } + else + { + err = APP_ERROR_UNHANDLED_EVENT; + action = ContactSensorManager::Action::kInvalid; + } + + if (err == CHIP_NO_ERROR) + { + ContactSensorMgr().InitiateAction(action); + } +} + +void AppTask::OTAHandler(void * aGenericEvent) +{ + AppEvent * aEvent = (AppEvent *) aGenericEvent; + if (aEvent->ButtonEvent.PinNo != OTA_BUTTON) + return; + +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR + if (sAppTask.mFunction != Function::kNoneSelected) + { + K32W_LOG("Another function is scheduled. Could not initiate OTA!"); + return; + } + + PlatformMgr().ScheduleWork(StartOTAQuery, 0); +#endif +} + +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR +void AppTask::StartOTAQuery(intptr_t arg) +{ + GetRequestorInstance()->TriggerImmediateQuery(); +} + +void AppTask::PostOTAResume() +{ + AppEvent event; + event.Type = AppEvent::kOTAResume; + event.Handler = OTAResumeEventHandler; + sAppTask.PostEvent(&event); +} + +void AppTask::OnScheduleInitOTA(chip::System::Layer * systemLayer, void * appState) +{ + if (sIsDnssdPlatformInitialized) + { + PlatformMgr().ScheduleWork(AppTask::InitOTA, 0); + } + else + { + CHIP_ERROR error = chip::DeviceLayer::SystemLayer().StartTimer( + chip::System::Clock::Milliseconds32(CHIP_DEVICE_CONFIG_INIT_OTA_DELAY), AppTask::OnScheduleInitOTA, nullptr); + + if (error != CHIP_NO_ERROR) + { + K32W_LOG("Failed to schedule OTA initialization timer."); + } + } +} +#endif + +void AppTask::BleHandler(void * aGenericEvent) +{ + AppEvent * aEvent = (AppEvent *) aGenericEvent; + + if (aEvent->ButtonEvent.PinNo != BLE_BUTTON) + return; + + if (sAppTask.mFunction != Function::kNoneSelected) + { + K32W_LOG("Another function is scheduled. Could not toggle BLE state!"); + return; + } + PlatformMgr().ScheduleWork(AppTask::BleStartAdvertising, 0); +} + +void AppTask::BleStartAdvertising(intptr_t arg) +{ + if (ConnectivityMgr().IsBLEAdvertisingEnabled()) + { + ConnectivityMgr().SetBLEAdvertisingEnabled(false); +#if !cPWR_UsePowerDownMode + sStatusLED.Set(false); +#endif + K32W_LOG("Stopped BLE Advertising!"); + } + else + { + ConnectivityMgr().SetBLEAdvertisingEnabled(true); + + if (chip::Server::GetInstance().GetCommissioningWindowManager().OpenBasicCommissioningWindow() == CHIP_NO_ERROR) + { +#if !cPWR_UsePowerDownMode + sStatusLED.Set(true); +#endif + K32W_LOG("Started BLE Advertising!"); + } + else + { + K32W_LOG("OpenBasicCommissioningWindow() failed"); + } + } +} + +void AppTask::MatterEventHandler(const ChipDeviceEvent * event, intptr_t) +{ + if (event->Type == DeviceEventType::kServiceProvisioningChange && event->ServiceProvisioningChange.IsServiceProvisioned) + { + if (event->ServiceProvisioningChange.IsServiceProvisioned) + { + sIsThreadProvisioned = TRUE; + } + else + { + sIsThreadProvisioned = FALSE; + } + } + +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR + if (event->Type == DeviceEventType::kOtaStateChanged && event->OtaStateChanged.newState == kOtaSpaceAvailable) + { + sAppTask.PostOTAResume(); + } + + if (event->Type == DeviceEventType::kDnssdPlatformInitialized) + { + K32W_LOG("Dnssd platform initialized."); + sIsDnssdPlatformInitialized = true; + } +#endif + +#if CONFIG_CHIP_NFC_COMMISSIONING + if (event->Type == DeviceEventType::kCHIPoBLEAdvertisingChange && event->CHIPoBLEAdvertisingChange.Result == kActivity_Stopped) + { + if (!NFCMgr().IsTagEmulationStarted()) + { + K32W_LOG("NFC Tag emulation is already stopped!"); + } + else + { + NFCMgr().StopTagEmulation(); + K32W_LOG("Stopped NFC Tag Emulation!"); + } + } + else if (event->Type == DeviceEventType::kCHIPoBLEAdvertisingChange && + event->CHIPoBLEAdvertisingChange.Result == kActivity_Started) + { + if (NFCMgr().IsTagEmulationStarted()) + { + K32W_LOG("NFC Tag emulation is already started!"); + } + else + { + ShareQRCodeOverNFC(chip::RendezvousInformationFlags(chip::RendezvousInformationFlag::kBLE)); + K32W_LOG("Started NFC Tag Emulation!"); + } + } +#endif +} + +void AppTask::CancelTimer() +{ + if (xTimerStop(sFunctionTimer, 0) == pdFAIL) + { + K32W_LOG("app timer stop() failed"); + } + + mResetTimerActive = false; +} + +void AppTask::StartTimer(uint32_t aTimeoutInMs) +{ + if (xTimerIsTimerActive(sFunctionTimer)) + { + K32W_LOG("app timer already started!"); + CancelTimer(); + } + + // timer is not active, change its period to required value (== restart). + // FreeRTOS- Block for a maximum of 100 ticks if the change period command + // cannot immediately be sent to the timer command queue. + if (xTimerChangePeriod(sFunctionTimer, aTimeoutInMs / portTICK_PERIOD_MS, 100) != pdPASS) + { + K32W_LOG("app timer start() failed"); + } + + mResetTimerActive = true; +} + +void AppTask::OnStateChanged(ContactSensorManager::State aState) +{ + // If the contact state was changed, update LED state and cluster state (only if button was pressed). + // - turn on the contact LED if contact sensor is in closed state. + // - turn off the lock LED if contact sensor is in opened state. + if (ContactSensorManager::State::kContactClosed == aState) + { + K32W_LOG("Contact state changed to closed.") +#if !cPWR_UsePowerDownMode + sContactSensorLED.Set(true); +#endif + } + else if (ContactSensorManager::State::kContactOpened == aState) + { + K32W_LOG("Contact state changed to opened.") +#if !cPWR_UsePowerDownMode + sContactSensorLED.Set(false); +#endif + } + + if (sAppTask.IsSyncClusterToButtonAction()) + { + sAppTask.UpdateClusterState(); + } + + sAppTask.mFunction = Function::kNoneSelected; +} + +void AppTask::OnIdentifyStart(Identify * identify) +{ + if (EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BLINK == identify->mCurrentEffectIdentifier) + { + if (Function::kNoneSelected != sAppTask.mFunction) + { + K32W_LOG("Another function is scheduled. Could not initiate Identify process!"); + return; + } + K32W_LOG("Identify process has started. Status LED should blink every 0.5 seconds."); + sAppTask.mFunction = Function::kIdentify; +#if !cPWR_UsePowerDownMode + sStatusLED.Set(false); + sStatusLED.Blink(500); +#endif + } +} + +void AppTask::OnIdentifyStop(Identify * identify) +{ + if (EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BLINK == identify->mCurrentEffectIdentifier) + { + K32W_LOG("Identify process has stopped."); + sAppTask.mFunction = Function::kNoneSelected; + } +} + +void AppTask::PostContactActionRequest(ContactSensorManager::Action aAction) +{ + AppEvent event; + event.Type = AppEvent::kContact; + event.ContactEvent.Action = static_cast(aAction); + event.Handler = ContactActionEventHandler; + PostEvent(&event); +} + +void AppTask::OTAResumeEventHandler(void * aGenericEvent) +{ + AppEvent * aEvent = (AppEvent *) aGenericEvent; + if (aEvent->Type == AppEvent::kOTAResume) + { +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR + if (gDownloader.GetState() == OTADownloader::State::kInProgress) + { + gImageProcessor.TriggerNewRequestForData(); + } +#endif + } +} + +void AppTask::PostEvent(const AppEvent * aEvent) +{ + portBASE_TYPE taskToWake = pdFALSE; + if (sAppEventQueue != NULL) + { + if (__get_IPSR()) + { + if (!xQueueSendToFrontFromISR(sAppEventQueue, aEvent, &taskToWake)) + { + K32W_LOG("Failed to post event to app task event queue"); + } + if (taskToWake) + { + portYIELD_FROM_ISR(taskToWake); + } + } + else if (!xQueueSend(sAppEventQueue, aEvent, 0)) + { + K32W_LOG("Failed to post event to app task event queue"); + } + } +} + +void AppTask::DispatchEvent(AppEvent * aEvent) +{ +#if defined(cPWR_UsePowerDownMode) && (cPWR_UsePowerDownMode) + /* specific processing for events sent from App_PostCallbackMessage (see main.cpp) */ + if (aEvent->Type == AppEvent::kEventType_Lp) + { + aEvent->Handler(aEvent->param); + } + else +#endif + + if (aEvent->Handler) + { + aEvent->Handler(aEvent); + } + else + { + K32W_LOG("Event received with no handler. Dropping event."); + } +} + +void AppTask::UpdateClusterState(void) +{ + PlatformMgr().ScheduleWork(UpdateClusterStateInternal, 0); +} +extern void logBooleanStateEvent(bool state); +void AppTask::UpdateClusterStateInternal(intptr_t arg) +{ + uint8_t newValue = ContactSensorMgr().IsContactClosed(); + + // write the new on/off value + EmberAfStatus status = emberAfWriteAttribute(1, ZCL_BOOLEAN_STATE_CLUSTER_ID, ZCL_STATE_VALUE_ATTRIBUTE_ID, + (uint8_t *) &newValue, ZCL_BOOLEAN_ATTRIBUTE_TYPE); + if (status != EMBER_ZCL_STATUS_SUCCESS) + { + ChipLogError(NotSpecified, "ERR: updating boolean status value %x", status); + } + logBooleanStateEvent(newValue); +} + +void AppTask::UpdateDeviceState(void) +{ + PlatformMgr().ScheduleWork(UpdateDeviceStateInternal, 0); +} + +void AppTask::UpdateDeviceStateInternal(intptr_t arg) +{ + bool stateValueAttrValue = 0; + + /* get onoff attribute value */ + (void) emberAfReadAttribute(1, ZCL_BOOLEAN_STATE_CLUSTER_ID, ZCL_STATE_VALUE_ATTRIBUTE_ID, (uint8_t *) &stateValueAttrValue, 1); +#if !cPWR_UsePowerDownMode + /* set the device state */ + sContactSensorLED.Set(stateValueAttrValue); +#endif +} + +extern "C" void OTAIdleActivities(void) +{ +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR + OTA_TransactionResume(); +#endif +} diff --git a/examples/contact-sensor-app/nxp/k32w/k32w0/main/ContactSensorManager.cpp b/examples/contact-sensor-app/nxp/k32w/k32w0/main/ContactSensorManager.cpp new file mode 100644 index 00000000000000..f053a37b478dee --- /dev/null +++ b/examples/contact-sensor-app/nxp/k32w/k32w0/main/ContactSensorManager.cpp @@ -0,0 +1,83 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * Copyright (c) 2022 Google LLC. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ContactSensorManager.h" + +#include "AppTask.h" +#include "FreeRTOS.h" + +#include "app_config.h" + +ContactSensorManager ContactSensorManager::sContactSensor; + +int ContactSensorManager::Init() +{ + int err = 0; + + mState = State::kContactOpened; + mCallbackStateChanged = nullptr; + + return err; +} + +void ContactSensorManager::SetCallback(CallbackStateChanged aCallbackStateChanged) +{ + mCallbackStateChanged = aCallbackStateChanged; +} + +bool ContactSensorManager::IsContactClosed() +{ + return mState == State::kContactClosed; +} + +void ContactSensorManager::InitiateAction(Action aAction) +{ + AppEvent event; + event.Type = AppEvent::kContact; + event.ContactEvent.Action = static_cast(aAction); + event.Handler = HandleAction; + GetAppTask().PostEvent(&event); +} + +void ContactSensorManager::HandleAction(void * aGenericEvent) +{ + AppEvent * event = static_cast(aGenericEvent); + Action action = static_cast(event->ContactEvent.Action); + // Change current state based on action: + // - if state is closed and action is signal lost, change state to opened + // - if state is opened and action is signal detected, change state to closed + // - else, the state/action combination does not change the state. + if (State::kContactClosed == sContactSensor.mState && Action::kSignalLost == action) + { + sContactSensor.mState = State::kContactOpened; + } + else if (State::kContactOpened == sContactSensor.mState && Action::kSignalDetected == action) + { + sContactSensor.mState = State::kContactClosed; + } + + if (sContactSensor.mCallbackStateChanged != nullptr) + { + sContactSensor.mCallbackStateChanged(sContactSensor.mState); + } + else + { + K32W_LOG("Callback for state change was not set. Please set an appropriate callback."); + } +} diff --git a/examples/contact-sensor-app/nxp/k32w/k32w0/main/ZclCallbacks.cpp b/examples/contact-sensor-app/nxp/k32w/k32w0/main/ZclCallbacks.cpp new file mode 100644 index 00000000000000..4664a02404fabb --- /dev/null +++ b/examples/contact-sensor-app/nxp/k32w/k32w0/main/ZclCallbacks.cpp @@ -0,0 +1,96 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "AppTask.h" +#include "ContactSensorManager.h" + +#include +#include +#include +#include +#include +#include + +using namespace ::chip; +using namespace ::chip::app; +using namespace ::chip::app::Clusters; +using namespace ::chip::app::Clusters::BooleanState; + +void MatterPostAttributeChangeCallback(const chip::app::ConcreteAttributePath & path, uint8_t type, uint16_t size, uint8_t * value) +{ + ChipLogProgress(Zcl, "MatterPostAttributeChangeCallback, value:%d\n", *value); + if (path.mClusterId != BooleanState::Id) + { + ChipLogProgress(Zcl, "Unknown cluster ID: " ChipLogFormatMEI, ChipLogValueMEI(path.mClusterId)); + return; + } + + if (path.mAttributeId != BooleanState::Attributes::StateValue::Id) + { + ChipLogProgress(Zcl, "Unknown attribute ID: " ChipLogFormatMEI, ChipLogValueMEI(path.mAttributeId)); + return; + } + + AppTask & task = GetAppTask(); + // If the callback is called after the cluster attribute was changed due to pressing a button, + // set the sync value to false. Both LED and attribute were updated at this point. + // On the other hand, if the cluster attribute was changed due to a cluster command, + // forward the request to AppTask in order to update the LED state. + if (task.IsSyncClusterToButtonAction()) + { + task.SetSyncClusterToButtonAction(false); + } + else + { + task.PostContactActionRequest(*value ? ContactSensorManager::Action::kSignalDetected + : ContactSensorManager::Action::kSignalLost); + } +} + +/** @brief OnOff Cluster Init + * + * This function is called when a specific cluster is initialized. It gives the + * application an opportunity to take care of cluster initialization procedures. + * It is called exactly once for each endpoint where cluster is present. + * + * @param endpoint Ver.: always + * + * TODO Issue #3841 + * emberAfOnOffClusterInitCallback happens before the stack initialize the cluster + * attributes to the default value. + * The logic here expects something similar to the deprecated Plugins callback + * emberAfPluginOnOffClusterServerPostInitCallback. + * + */ +void emberAfBooleanStateClusterInitCallback(EndpointId endpoint) +{ + ChipLogProgress(Zcl, "emberAfBooleanStateClusterInitCallback\n"); + GetAppTask().UpdateClusterState(); +} + +void logBooleanStateEvent(bool state) +{ + EventNumber eventNumber; + Events::StateChange::Type event{ state }; + if (CHIP_NO_ERROR != LogEvent(event, 1, eventNumber)) + { + ChipLogProgress(Zcl, "booleanstate: failed to reacord state-change event"); + } +} diff --git a/examples/contact-sensor-app/nxp/k32w/k32w0/main/include/AppEvent.h b/examples/contact-sensor-app/nxp/k32w/k32w0/main/include/AppEvent.h new file mode 100644 index 00000000000000..3d7f4367ccaeb8 --- /dev/null +++ b/examples/contact-sensor-app/nxp/k32w/k32w0/main/include/AppEvent.h @@ -0,0 +1,62 @@ +/* + * + * Copyright (c) 2022 Nest Labs, Inc. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +struct AppEvent; +typedef void (*EventHandler)(void *); + +struct AppEvent +{ + enum AppEventTypes + { + kButton = 0, + kTimer, + kContact, + kInstall, +#if defined(cPWR_UsePowerDownMode) && (cPWR_UsePowerDownMode) + kEventType_Lp, +#endif + kOTAResume, + }; + + AppEventTypes Type; + + union + { + struct + { + uint8_t PinNo; + uint8_t Action; + } ButtonEvent; + struct + { + void * Context; + } TimerEvent; + struct + { + uint8_t Action; + } ContactEvent; + }; + + EventHandler Handler; + +#if defined(cPWR_UsePowerDownMode) && (cPWR_UsePowerDownMode) + void * param; +#endif +}; diff --git a/examples/contact-sensor-app/nxp/k32w/k32w0/main/include/AppTask.h b/examples/contact-sensor-app/nxp/k32w/k32w0/main/include/AppTask.h new file mode 100644 index 00000000000000..029e0205cdf937 --- /dev/null +++ b/examples/contact-sensor-app/nxp/k32w/k32w0/main/include/AppTask.h @@ -0,0 +1,131 @@ +/* + * + * Copyright (c) 2022 Google LLC. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include + +#include "AppEvent.h" +#include "ContactSensorManager.h" +#include "K32W0FactoryDataProvider.h" + +#include +#include + +#include "FreeRTOS.h" +#include "timers.h" + +// Application-defined error codes in the CHIP_ERROR space. +#define APP_ERROR_EVENT_QUEUE_FAILED CHIP_APPLICATION_ERROR(0x01) +#define APP_ERROR_CREATE_TASK_FAILED CHIP_APPLICATION_ERROR(0x02) +#define APP_ERROR_UNHANDLED_EVENT CHIP_APPLICATION_ERROR(0x03) +#define APP_ERROR_CREATE_TIMER_FAILED CHIP_APPLICATION_ERROR(0x04) +#define APP_ERROR_START_TIMER_FAILED CHIP_APPLICATION_ERROR(0x05) +#define APP_ERROR_STOP_TIMER_FAILED CHIP_APPLICATION_ERROR(0x06) + +class AppTask +{ +public: + CHIP_ERROR StartAppTask(); + static void AppTaskMain(void * pvParameter); + + void PostContactActionRequest(ContactSensorManager::Action aAction); + void PostEvent(const AppEvent * event); + + void UpdateClusterState(void); + void UpdateDeviceState(void); + + bool IsSyncClusterToButtonAction(); + void SetSyncClusterToButtonAction(bool value); + // Identify cluster callbacks. + static void OnIdentifyStart(Identify * identify); + static void OnIdentifyStop(Identify * identify); + +private: + friend AppTask & GetAppTask(void); + + CHIP_ERROR Init(); + + static void OnStateChanged(ContactSensorManager::State aState); + + void CancelTimer(void); + + void DispatchEvent(AppEvent * event); + + static void FunctionTimerEventHandler(void * aGenericEvent); + static void KBD_Callback(uint8_t events); + static void HandleKeyboard(void); + static void OTAHandler(void * aGenericEvent); + static void BleHandler(void * aGenericEvent); + static void BleStartAdvertising(intptr_t arg); + static void ContactActionEventHandler(void * aGenericEvent); + static void OTAResumeEventHandler(void * aGenericEvent); + static void ResetActionEventHandler(void * aGenericEvent); + static void InstallEventHandler(void * aGenericEvent); + + static void ButtonEventHandler(uint8_t pin_no, uint8_t button_action); + static void TimerEventHandler(TimerHandle_t xTimer); + + static void MatterEventHandler(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg); + void StartTimer(uint32_t aTimeoutInMs); + +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR + static void InitOTA(intptr_t arg); + static void StartOTAQuery(intptr_t arg); + static void PostOTAResume(); + static void OnScheduleInitOTA(chip::System::Layer * systemLayer, void * appState); +#endif + + static void UpdateClusterStateInternal(intptr_t arg); + static void UpdateDeviceStateInternal(intptr_t arg); + static void InitServer(intptr_t arg); + + enum class Function : uint8_t + { + kNoneSelected = 0, + kSoftwareUpdate = 0, + kFactoryReset, + kContact, + kIdentify, + kInvalid + }; + + Function mFunction = Function::kNoneSelected; + bool mResetTimerActive = false; + bool mSyncClusterToButtonAction = false; + + static AppTask sAppTask; + + chip::DeviceLayer::K32W0FactoryDataProvider mK32W0FactoryDataProvider; +}; + +inline AppTask & GetAppTask(void) +{ + return AppTask::sAppTask; +} + +inline bool AppTask::IsSyncClusterToButtonAction() +{ + return mSyncClusterToButtonAction; +} + +inline void AppTask::SetSyncClusterToButtonAction(bool value) +{ + mSyncClusterToButtonAction = value; +} diff --git a/examples/contact-sensor-app/nxp/k32w/k32w0/main/include/ContactSensorManager.h b/examples/contact-sensor-app/nxp/k32w/k32w0/main/include/ContactSensorManager.h new file mode 100644 index 00000000000000..29db3afbe51fdd --- /dev/null +++ b/examples/contact-sensor-app/nxp/k32w/k32w0/main/include/ContactSensorManager.h @@ -0,0 +1,65 @@ +/* + * + * Copyright (c) 2022 Google LLC. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include + +#include "AppEvent.h" + +#include "FreeRTOS.h" +#include "timers.h" // provides FreeRTOS timer support + +class ContactSensorManager +{ +public: + enum class Action : uint8_t + { + kSignalDetected = 0, + kSignalLost, + kInvalid + }; + + enum class State : uint8_t + { + kContactClosed = 0, + kContactOpened, + kInvalid + }; + + int Init(); + bool IsContactClosed(); + void InitiateAction(Action aAction); + + typedef void (*CallbackStateChanged)(State aState); + void SetCallback(CallbackStateChanged aCallbackStateChanged); + + static void HandleAction(void * aGenericEvent); + +private: + friend ContactSensorManager & ContactSensorMgr(void); + State mState; + CallbackStateChanged mCallbackStateChanged; + static ContactSensorManager sContactSensor; +}; + +inline ContactSensorManager & ContactSensorMgr(void) +{ + return ContactSensorManager::sContactSensor; +} diff --git a/examples/contact-sensor-app/nxp/k32w/k32w0/main/include/app_config.h b/examples/contact-sensor-app/nxp/k32w/k32w0/main/include/app_config.h new file mode 100644 index 00000000000000..2e32f6475c4f46 --- /dev/null +++ b/examples/contact-sensor-app/nxp/k32w/k32w0/main/include/app_config.h @@ -0,0 +1,56 @@ +/* + * + * Copyright (c) 2022 Google LLC. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "LED.h" + +#pragma once + +// ---- Contact Example App Config ---- + +#define RESET_BUTTON 1 +#define CONTACT_SENSOR_BUTTON 2 +#define OTA_BUTTON 3 +#define BLE_BUTTON 4 + +#define RESET_BUTTON_PUSH 1 +#define CONTACT_SENSOR_BUTTON_PUSH 2 +#define OTA_BUTTON_PUSH 3 +#define BLE_BUTTON_PUSH 4 + +#define APP_BUTTON_PUSH 1 + +#define CONTACT_SENSOR_STATE_LED LED1 +#define SYSTEM_STATE_LED LED2 + +// ---- Contact Example SWU Config ---- +#define SWU_INTERVAl_WINDOW_MIN_MS (23 * 60 * 60 * 1000) // 23 hours +#define SWU_INTERVAl_WINDOW_MAX_MS (24 * 60 * 60 * 1000) // 24 hours + +// ---- Thread Polling Config ---- +#define THREAD_ACTIVE_POLLING_INTERVAL_MS 100 +#define THREAD_INACTIVE_POLLING_INTERVAL_MS 1000 + +#if K32W_LOG_ENABLED +#if CHIP_PW_TOKENIZER_LOGGING +#define K32W_LOG(MSG, ...) ChipLogDetail(Echo, MSG, __VA_ARGS__); +#else +#define K32W_LOG(...) otPlatLog(OT_LOG_LEVEL_NONE, OT_LOG_REGION_API, ##__VA_ARGS__); +#endif +#else +#define K32W_LOG(...) +#endif diff --git a/examples/contact-sensor-app/nxp/k32w/k32w0/main/main.cpp b/examples/contact-sensor-app/nxp/k32w/k32w0/main/main.cpp new file mode 100644 index 00000000000000..fcba2385479876 --- /dev/null +++ b/examples/contact-sensor-app/nxp/k32w/k32w0/main/main.cpp @@ -0,0 +1,201 @@ +/* + * + * Copyright (c) 2022 Google LLC. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// ================================================================================ +// Main Code +// ================================================================================ + +#include + +#include +#include +#include +#include +#include + +#include "FreeRtosHooks.h" +#include "app_config.h" + +using namespace ::chip; +using namespace ::chip::Inet; +using namespace ::chip::DeviceLayer; +using namespace ::chip::Logging; + +#include "MacSched.h" + +#ifdef K32WMCM_APP_BUILD +#define string string_shadow +#include "AppApi.h" +#include "MMAC.h" +#include "mac_sap.h" +#undef string +#endif + +typedef void (*InitFunc)(void); +extern InitFunc __init_array_start; +extern InitFunc __init_array_end; + +#define NORMAL_PWR_LIMIT 10 /* dBm */ + +#ifdef K32WMCM_APP_BUILD +/* Must be called before zps_eAplAfInit() */ +void APP_SetHighTxPowerMode(); + +/* Must be called after zps_eAplAfInit() */ +void APP_SetMaxTxPower(); + +#undef HIGH_TX_PWR_LIMIT +#define HIGH_TX_PWR_LIMIT 15 /* dBm */ +/* High Tx power */ +void APP_SetHighTxPowerMode() +{ + if (CHIP_IS_HITXPOWER_CAPABLE()) + vMMAC_SetTxPowerMode(TRUE); +} + +void APP_SetMaxTxPower() +{ + if (CHIP_IS_HITXPOWER_CAPABLE()) + eAppApiPlmeSet(PHY_PIB_ATTR_TX_POWER, HIGH_TX_PWR_LIMIT); +} +#endif + +/* low power requirements */ +#if defined(cPWR_UsePowerDownMode) && (cPWR_UsePowerDownMode) +extern "C" void setThreadInitialized(bool isInitialized); +extern "C" bool isThreadInitialized(); +#endif + +/* needed for FreeRtos Heap 4 */ +uint8_t __attribute__((section(".heap"))) ucHeap[HEAP_SIZE]; + +extern "C" void sched_enable(); + +extern "C" void main_task(void const * argument) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + /* Call C++ constructors */ + InitFunc * pFunc = &__init_array_start; + for (; pFunc < &__init_array_end; ++pFunc) + { + (*pFunc)(); + } + + mbedtls_platform_set_calloc_free(CHIPPlatformMemoryCalloc, CHIPPlatformMemoryFree); + + err = PlatformMgrImpl().InitBoardFwk(); + + if (err != CHIP_NO_ERROR) + { + return; + } + + K32W_LOG("Welcome to NXP Contact Sensor Demo App"); + + /* Mbedtls Threading support is needed because both + * Thread and Matter tasks are using it */ + freertos_mbedtls_mutex_init(); + + // Init Chip memory management before the stack + chip::Platform::MemoryInit(); + +#ifdef K32WMCM_APP_BUILD + APP_SetHighTxPowerMode(); +#endif + + err = PlatformMgr().InitChipStack(); + if (err != CHIP_NO_ERROR) + { + K32W_LOG("Error during PlatformMgr().InitMatterStack()"); + goto exit; + } + + err = ThreadStackMgr().InitThreadStack(); + if (err != CHIP_NO_ERROR) + { + K32W_LOG("Error during ThreadStackMgr().InitThreadStack()"); + goto exit; + } + + /* Enable the MAC scheduler after BLEManagerImpl::_Init() and V2MMAC_Enable(). + * This is needed to register properly the active protocols. + */ + sched_enable(); + + err = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_SleepyEndDevice); + if (err != CHIP_NO_ERROR) + { + goto exit; + } + +#if defined(cPWR_UsePowerDownMode) && (cPWR_UsePowerDownMode) + setThreadInitialized(TRUE); +#endif + +#ifdef K32WMCM_APP_BUILD + APP_SetMaxTxPower(); + otPlatRadioSetTransmitPower(ThreadStackMgrImpl().OTInstance(), HIGH_TX_PWR_LIMIT); +#else + otPlatRadioSetTransmitPower(ThreadStackMgrImpl().OTInstance(), NORMAL_PWR_LIMIT); +#endif + + // Start OpenThread task + err = ThreadStackMgrImpl().StartThreadTask(); + if (err != CHIP_NO_ERROR) + { + K32W_LOG("Error during ThreadStackMgrImpl().StartThreadTask()"); + goto exit; + } + + err = GetAppTask().StartAppTask(); + if (err != CHIP_NO_ERROR) + { + K32W_LOG("Error during GetAppTask().StartAppTask()"); + goto exit; + } + + err = PlatformMgr().StartEventLoopTask(); + if (err != CHIP_NO_ERROR) + { + K32W_LOG("Error during PlatformMgr().StartEventLoopTask();"); + goto exit; + } + + GetAppTask().AppTaskMain(NULL); + +exit: + return; +} + +/** + * Glue function called directly by the OpenThread stack + * when system event processing work is pending. + */ +extern "C" void otSysEventSignalPending(void) +{ + +#if defined(cPWR_UsePowerDownMode) && (cPWR_UsePowerDownMode) + /* make sure that 15.4 radio is initialized before waking up the Thread task */ + if (isThreadInitialized()) +#endif + { + BaseType_t yieldRequired = ThreadStackMgrImpl().SignalThreadActivityPendingFromISR(); + portYIELD_FROM_ISR(yieldRequired); + } +} diff --git a/examples/contact-sensor-app/nxp/k32w/k32w0/third_party/connectedhomeip b/examples/contact-sensor-app/nxp/k32w/k32w0/third_party/connectedhomeip new file mode 120000 index 00000000000000..305f2077ffe860 --- /dev/null +++ b/examples/contact-sensor-app/nxp/k32w/k32w0/third_party/connectedhomeip @@ -0,0 +1 @@ +../../../../../.. \ No newline at end of file diff --git a/scripts/build/build/targets.py b/scripts/build/build/targets.py index 976fc80381c506..033d6fe758ad1f 100755 --- a/scripts/build/build/targets.py +++ b/scripts/build/build/targets.py @@ -559,6 +559,9 @@ def K32WTargets(): yield target.Extend('lock-release', app=K32WApp.LOCK, release=True) yield target.Extend('lock-low-power-release', app=K32WApp.LOCK, low_power=True, disable_logs=True, release=True).GlobBlacklist("Only on demand build") + yield target.Extend('contact-release', app=K32WApp.CONTACT, tokenizer=True, release=True, tinycrypt=True) + yield target.Extend('contact-low-power-release', app=K32WApp.CONTACT, tokenizer=True, tinycrypt=True, + low_power=True, disable_logs=True, release=True).GlobBlacklist("Only on demand build") def cc13x2x7_26x2x7Targets(): diff --git a/scripts/build/builders/k32w.py b/scripts/build/builders/k32w.py index f00c21a5ac3344..eb367cc644c5c0 100644 --- a/scripts/build/builders/k32w.py +++ b/scripts/build/builders/k32w.py @@ -22,6 +22,7 @@ class K32WApp(Enum): LIGHT = auto() LOCK = auto() SHELL = auto() + CONTACT = auto() def ExampleName(self): if self == K32WApp.LIGHT: @@ -30,6 +31,8 @@ def ExampleName(self): return 'lock-app' elif self == K32WApp.SHELL: return 'shell' + elif self == K32WApp.CONTACT: + return "contact-sensor-app" else: raise Exception('Unknown app type: %r' % self) diff --git a/scripts/build/testdata/all_targets_except_host.txt b/scripts/build/testdata/all_targets_except_host.txt index 247535b2ba885a..d1f5868963d6b1 100644 --- a/scripts/build/testdata/all_targets_except_host.txt +++ b/scripts/build/testdata/all_targets_except_host.txt @@ -213,6 +213,8 @@ infineon-psoc6-lock infineon-psoc6-lock-ota (NOGLOB: Reduce default build variants) infineon-psoc6-lock-ota-updateimage (NOGLOB: Reduce default build variants) infineon-psoc6-lock-updateimage (NOGLOB: Reduce default build variants) +k32w-contact-low-power-release (NOGLOB: Only on demand build) +k32w-contact-release k32w-light-ota-se (NOGLOB: Only on demand build) k32w-light-release-no-ota k32w-lock-low-power-release (NOGLOB: Only on demand build) diff --git a/scripts/build/testdata/build_all_except_host.txt b/scripts/build/testdata/build_all_except_host.txt index b131ac868ecadc..4fc2526a63d102 100644 --- a/scripts/build/testdata/build_all_except_host.txt +++ b/scripts/build/testdata/build_all_except_host.txt @@ -958,6 +958,16 @@ gn gen --check --fail-on-unused-args --export-compile-commands --root={root}/exa {root}/third_party/nxp/k32w0_sdk/sdk_fixes/patch_k32w_sdk.sh +# Generating k32w-contact-low-power-release +gn gen --check --fail-on-unused-args --export-compile-commands --root={root}/examples/contact-sensor-app/nxp/k32w/k32w0 '--args=k32w0_sdk_root="TEST_NXP_K32W0_SDK_ROOT" chip_with_low_power=1 chip_pw_tokenizer_logging=true is_debug=false chip_logging=false chip_crypto="tinycrypt" mbedtls_repo="//third_party/connectedhomeip/third_party/nxp/libs/mbedtls"' {out}/k32w-contact-low-power-release + +{root}/third_party/nxp/k32w0_sdk/sdk_fixes/patch_k32w_sdk.sh + +# Generating k32w-contact-release +gn gen --check --fail-on-unused-args --export-compile-commands --root={root}/examples/contact-sensor-app/nxp/k32w/k32w0 '--args=k32w0_sdk_root="TEST_NXP_K32W0_SDK_ROOT" chip_with_low_power=0 chip_pw_tokenizer_logging=true is_debug=false chip_crypto="tinycrypt" mbedtls_repo="//third_party/connectedhomeip/third_party/nxp/libs/mbedtls"' {out}/k32w-contact-release + +{root}/third_party/nxp/k32w0_sdk/sdk_fixes/patch_k32w_sdk.sh + # Generating k32w-light-ota-se gn gen --check --fail-on-unused-args --export-compile-commands --root={root}/examples/lighting-app/nxp/k32w/k32w0 '--args=k32w0_sdk_root="TEST_NXP_K32W0_SDK_ROOT" chip_with_low_power=0 is_debug=false chip_enable_ble=false chip_with_se05x=true' {out}/k32w-light-ota-se @@ -2284,6 +2294,12 @@ ninja -C {out}/infineon-psoc6-lock-ota-updateimage # Building infineon-psoc6-lock-updateimage ninja -C {out}/infineon-psoc6-lock-updateimage +# Building k32w-contact-low-power-release +ninja -C {out}/k32w-contact-low-power-release + +# Building k32w-contact-release +ninja -C {out}/k32w-contact-release + # Building k32w-light-ota-se ninja -C {out}/k32w-light-ota-se diff --git a/scripts/build/testdata/glob_star_targets_except_host.txt b/scripts/build/testdata/glob_star_targets_except_host.txt index 15ba044b6a52e4..334b88c2e8dbfe 100644 --- a/scripts/build/testdata/glob_star_targets_except_host.txt +++ b/scripts/build/testdata/glob_star_targets_except_host.txt @@ -88,6 +88,7 @@ infineon-psoc6-all-clusters infineon-psoc6-all-clusters-minimal infineon-psoc6-light infineon-psoc6-lock +k32w-contact-release k32w-light-release-no-ota k32w-lock-release k32w-shell-release diff --git a/zzz_generated/contact-sensor-app/zap-generated/CHIPClientCallbacks.h b/zzz_generated/contact-sensor-app/zap-generated/CHIPClientCallbacks.h new file mode 100644 index 00000000000000..4458f51745a59b --- /dev/null +++ b/zzz_generated/contact-sensor-app/zap-generated/CHIPClientCallbacks.h @@ -0,0 +1,32 @@ +/* + * + * 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 + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// List specific responses diff --git a/zzz_generated/contact-sensor-app/zap-generated/CHIPClusters.h b/zzz_generated/contact-sensor-app/zap-generated/CHIPClusters.h new file mode 100644 index 00000000000000..fffb265ae9c797 --- /dev/null +++ b/zzz_generated/contact-sensor-app/zap-generated/CHIPClusters.h @@ -0,0 +1,44 @@ +/* + * + * 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 + +// Prevent multiple inclusion +#pragma once + +#include +#include + +#include +#include +#include + +namespace chip { +namespace Controller { + +class DLL_EXPORT OtaSoftwareUpdateProviderCluster : public ClusterBase +{ +public: + OtaSoftwareUpdateProviderCluster(Messaging::ExchangeManager & exchangeManager, const SessionHandle & session, + EndpointId endpoint) : + ClusterBase(exchangeManager, session, app::Clusters::OtaSoftwareUpdateProvider::Id, endpoint) + {} + ~OtaSoftwareUpdateProviderCluster() {} +}; + +} // namespace Controller +} // namespace chip diff --git a/zzz_generated/contact-sensor-app/zap-generated/IMClusterCommandHandler.cpp b/zzz_generated/contact-sensor-app/zap-generated/IMClusterCommandHandler.cpp new file mode 100644 index 00000000000000..c7d1360efc3716 --- /dev/null +++ b/zzz_generated/contact-sensor-app/zap-generated/IMClusterCommandHandler.cpp @@ -0,0 +1,857 @@ +/* + * + * 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 + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Currently we need some work to keep compatible with ember lib. +#include + +namespace chip { +namespace app { + +// Cluster specific command parsing + +namespace Clusters { + +namespace AdministratorCommissioning { + +void DispatchServerCommand(CommandHandler * apCommandObj, const ConcreteCommandPath & aCommandPath, TLV::TLVReader & aDataTlv) +{ + CHIP_ERROR TLVError = CHIP_NO_ERROR; + bool wasHandled = false; + { + switch (aCommandPath.mCommandId) + { + case Commands::OpenCommissioningWindow::Id: { + Commands::OpenCommissioningWindow::DecodableType commandData; + TLVError = DataModel::Decode(aDataTlv, commandData); + if (TLVError == CHIP_NO_ERROR) + { + wasHandled = emberAfAdministratorCommissioningClusterOpenCommissioningWindowCallback(apCommandObj, aCommandPath, + commandData); + } + break; + } + case Commands::OpenBasicCommissioningWindow::Id: { + Commands::OpenBasicCommissioningWindow::DecodableType commandData; + TLVError = DataModel::Decode(aDataTlv, commandData); + if (TLVError == CHIP_NO_ERROR) + { + wasHandled = emberAfAdministratorCommissioningClusterOpenBasicCommissioningWindowCallback( + apCommandObj, aCommandPath, commandData); + } + break; + } + case Commands::RevokeCommissioning::Id: { + Commands::RevokeCommissioning::DecodableType commandData; + TLVError = DataModel::Decode(aDataTlv, commandData); + if (TLVError == CHIP_NO_ERROR) + { + wasHandled = + emberAfAdministratorCommissioningClusterRevokeCommissioningCallback(apCommandObj, aCommandPath, commandData); + } + break; + } + default: { + // Unrecognized command ID, error status will apply. + apCommandObj->AddStatus(aCommandPath, Protocols::InteractionModel::Status::UnsupportedCommand); + ChipLogError(Zcl, "Unknown command " ChipLogFormatMEI " for cluster " ChipLogFormatMEI, + ChipLogValueMEI(aCommandPath.mCommandId), ChipLogValueMEI(aCommandPath.mClusterId)); + return; + } + } + } + + if (CHIP_NO_ERROR != TLVError || !wasHandled) + { + apCommandObj->AddStatus(aCommandPath, Protocols::InteractionModel::Status::InvalidCommand); + ChipLogProgress(Zcl, "Failed to dispatch command, TLVError=%" CHIP_ERROR_FORMAT, TLVError.Format()); + } +} + +} // namespace AdministratorCommissioning + +namespace DiagnosticLogs { + +void DispatchServerCommand(CommandHandler * apCommandObj, const ConcreteCommandPath & aCommandPath, TLV::TLVReader & aDataTlv) +{ + CHIP_ERROR TLVError = CHIP_NO_ERROR; + bool wasHandled = false; + { + switch (aCommandPath.mCommandId) + { + case Commands::RetrieveLogsRequest::Id: { + Commands::RetrieveLogsRequest::DecodableType commandData; + TLVError = DataModel::Decode(aDataTlv, commandData); + if (TLVError == CHIP_NO_ERROR) + { + wasHandled = emberAfDiagnosticLogsClusterRetrieveLogsRequestCallback(apCommandObj, aCommandPath, commandData); + } + break; + } + default: { + // Unrecognized command ID, error status will apply. + apCommandObj->AddStatus(aCommandPath, Protocols::InteractionModel::Status::UnsupportedCommand); + ChipLogError(Zcl, "Unknown command " ChipLogFormatMEI " for cluster " ChipLogFormatMEI, + ChipLogValueMEI(aCommandPath.mCommandId), ChipLogValueMEI(aCommandPath.mClusterId)); + return; + } + } + } + + if (CHIP_NO_ERROR != TLVError || !wasHandled) + { + apCommandObj->AddStatus(aCommandPath, Protocols::InteractionModel::Status::InvalidCommand); + ChipLogProgress(Zcl, "Failed to dispatch command, TLVError=%" CHIP_ERROR_FORMAT, TLVError.Format()); + } +} + +} // namespace DiagnosticLogs + +namespace EthernetNetworkDiagnostics { + +void DispatchServerCommand(CommandHandler * apCommandObj, const ConcreteCommandPath & aCommandPath, TLV::TLVReader & aDataTlv) +{ + CHIP_ERROR TLVError = CHIP_NO_ERROR; + bool wasHandled = false; + { + switch (aCommandPath.mCommandId) + { + case Commands::ResetCounts::Id: { + Commands::ResetCounts::DecodableType commandData; + TLVError = DataModel::Decode(aDataTlv, commandData); + if (TLVError == CHIP_NO_ERROR) + { + wasHandled = emberAfEthernetNetworkDiagnosticsClusterResetCountsCallback(apCommandObj, aCommandPath, commandData); + } + break; + } + default: { + // Unrecognized command ID, error status will apply. + apCommandObj->AddStatus(aCommandPath, Protocols::InteractionModel::Status::UnsupportedCommand); + ChipLogError(Zcl, "Unknown command " ChipLogFormatMEI " for cluster " ChipLogFormatMEI, + ChipLogValueMEI(aCommandPath.mCommandId), ChipLogValueMEI(aCommandPath.mClusterId)); + return; + } + } + } + + if (CHIP_NO_ERROR != TLVError || !wasHandled) + { + apCommandObj->AddStatus(aCommandPath, Protocols::InteractionModel::Status::InvalidCommand); + ChipLogProgress(Zcl, "Failed to dispatch command, TLVError=%" CHIP_ERROR_FORMAT, TLVError.Format()); + } +} + +} // namespace EthernetNetworkDiagnostics + +namespace GeneralCommissioning { + +void DispatchServerCommand(CommandHandler * apCommandObj, const ConcreteCommandPath & aCommandPath, TLV::TLVReader & aDataTlv) +{ + CHIP_ERROR TLVError = CHIP_NO_ERROR; + bool wasHandled = false; + { + switch (aCommandPath.mCommandId) + { + case Commands::ArmFailSafe::Id: { + Commands::ArmFailSafe::DecodableType commandData; + TLVError = DataModel::Decode(aDataTlv, commandData); + if (TLVError == CHIP_NO_ERROR) + { + wasHandled = emberAfGeneralCommissioningClusterArmFailSafeCallback(apCommandObj, aCommandPath, commandData); + } + break; + } + case Commands::SetRegulatoryConfig::Id: { + Commands::SetRegulatoryConfig::DecodableType commandData; + TLVError = DataModel::Decode(aDataTlv, commandData); + if (TLVError == CHIP_NO_ERROR) + { + wasHandled = emberAfGeneralCommissioningClusterSetRegulatoryConfigCallback(apCommandObj, aCommandPath, commandData); + } + break; + } + case Commands::CommissioningComplete::Id: { + Commands::CommissioningComplete::DecodableType commandData; + TLVError = DataModel::Decode(aDataTlv, commandData); + if (TLVError == CHIP_NO_ERROR) + { + wasHandled = + emberAfGeneralCommissioningClusterCommissioningCompleteCallback(apCommandObj, aCommandPath, commandData); + } + break; + } + default: { + // Unrecognized command ID, error status will apply. + apCommandObj->AddStatus(aCommandPath, Protocols::InteractionModel::Status::UnsupportedCommand); + ChipLogError(Zcl, "Unknown command " ChipLogFormatMEI " for cluster " ChipLogFormatMEI, + ChipLogValueMEI(aCommandPath.mCommandId), ChipLogValueMEI(aCommandPath.mClusterId)); + return; + } + } + } + + if (CHIP_NO_ERROR != TLVError || !wasHandled) + { + apCommandObj->AddStatus(aCommandPath, Protocols::InteractionModel::Status::InvalidCommand); + ChipLogProgress(Zcl, "Failed to dispatch command, TLVError=%" CHIP_ERROR_FORMAT, TLVError.Format()); + } +} + +} // namespace GeneralCommissioning + +namespace GeneralDiagnostics { + +void DispatchServerCommand(CommandHandler * apCommandObj, const ConcreteCommandPath & aCommandPath, TLV::TLVReader & aDataTlv) +{ + CHIP_ERROR TLVError = CHIP_NO_ERROR; + bool wasHandled = false; + { + switch (aCommandPath.mCommandId) + { + case Commands::TestEventTrigger::Id: { + Commands::TestEventTrigger::DecodableType commandData; + TLVError = DataModel::Decode(aDataTlv, commandData); + if (TLVError == CHIP_NO_ERROR) + { + wasHandled = emberAfGeneralDiagnosticsClusterTestEventTriggerCallback(apCommandObj, aCommandPath, commandData); + } + break; + } + default: { + // Unrecognized command ID, error status will apply. + apCommandObj->AddStatus(aCommandPath, Protocols::InteractionModel::Status::UnsupportedCommand); + ChipLogError(Zcl, "Unknown command " ChipLogFormatMEI " for cluster " ChipLogFormatMEI, + ChipLogValueMEI(aCommandPath.mCommandId), ChipLogValueMEI(aCommandPath.mClusterId)); + return; + } + } + } + + if (CHIP_NO_ERROR != TLVError || !wasHandled) + { + apCommandObj->AddStatus(aCommandPath, Protocols::InteractionModel::Status::InvalidCommand); + ChipLogProgress(Zcl, "Failed to dispatch command, TLVError=%" CHIP_ERROR_FORMAT, TLVError.Format()); + } +} + +} // namespace GeneralDiagnostics + +namespace GroupKeyManagement { + +void DispatchServerCommand(CommandHandler * apCommandObj, const ConcreteCommandPath & aCommandPath, TLV::TLVReader & aDataTlv) +{ + CHIP_ERROR TLVError = CHIP_NO_ERROR; + bool wasHandled = false; + { + switch (aCommandPath.mCommandId) + { + case Commands::KeySetWrite::Id: { + Commands::KeySetWrite::DecodableType commandData; + TLVError = DataModel::Decode(aDataTlv, commandData); + if (TLVError == CHIP_NO_ERROR) + { + wasHandled = emberAfGroupKeyManagementClusterKeySetWriteCallback(apCommandObj, aCommandPath, commandData); + } + break; + } + case Commands::KeySetRead::Id: { + Commands::KeySetRead::DecodableType commandData; + TLVError = DataModel::Decode(aDataTlv, commandData); + if (TLVError == CHIP_NO_ERROR) + { + wasHandled = emberAfGroupKeyManagementClusterKeySetReadCallback(apCommandObj, aCommandPath, commandData); + } + break; + } + case Commands::KeySetRemove::Id: { + Commands::KeySetRemove::DecodableType commandData; + TLVError = DataModel::Decode(aDataTlv, commandData); + if (TLVError == CHIP_NO_ERROR) + { + wasHandled = emberAfGroupKeyManagementClusterKeySetRemoveCallback(apCommandObj, aCommandPath, commandData); + } + break; + } + case Commands::KeySetReadAllIndices::Id: { + Commands::KeySetReadAllIndices::DecodableType commandData; + TLVError = DataModel::Decode(aDataTlv, commandData); + if (TLVError == CHIP_NO_ERROR) + { + wasHandled = emberAfGroupKeyManagementClusterKeySetReadAllIndicesCallback(apCommandObj, aCommandPath, commandData); + } + break; + } + default: { + // Unrecognized command ID, error status will apply. + apCommandObj->AddStatus(aCommandPath, Protocols::InteractionModel::Status::UnsupportedCommand); + ChipLogError(Zcl, "Unknown command " ChipLogFormatMEI " for cluster " ChipLogFormatMEI, + ChipLogValueMEI(aCommandPath.mCommandId), ChipLogValueMEI(aCommandPath.mClusterId)); + return; + } + } + } + + if (CHIP_NO_ERROR != TLVError || !wasHandled) + { + apCommandObj->AddStatus(aCommandPath, Protocols::InteractionModel::Status::InvalidCommand); + ChipLogProgress(Zcl, "Failed to dispatch command, TLVError=%" CHIP_ERROR_FORMAT, TLVError.Format()); + } +} + +} // namespace GroupKeyManagement + +namespace Groups { + +void DispatchServerCommand(CommandHandler * apCommandObj, const ConcreteCommandPath & aCommandPath, TLV::TLVReader & aDataTlv) +{ + CHIP_ERROR TLVError = CHIP_NO_ERROR; + bool wasHandled = false; + { + switch (aCommandPath.mCommandId) + { + case Commands::AddGroup::Id: { + Commands::AddGroup::DecodableType commandData; + TLVError = DataModel::Decode(aDataTlv, commandData); + if (TLVError == CHIP_NO_ERROR) + { + wasHandled = emberAfGroupsClusterAddGroupCallback(apCommandObj, aCommandPath, commandData); + } + break; + } + case Commands::ViewGroup::Id: { + Commands::ViewGroup::DecodableType commandData; + TLVError = DataModel::Decode(aDataTlv, commandData); + if (TLVError == CHIP_NO_ERROR) + { + wasHandled = emberAfGroupsClusterViewGroupCallback(apCommandObj, aCommandPath, commandData); + } + break; + } + case Commands::GetGroupMembership::Id: { + Commands::GetGroupMembership::DecodableType commandData; + TLVError = DataModel::Decode(aDataTlv, commandData); + if (TLVError == CHIP_NO_ERROR) + { + wasHandled = emberAfGroupsClusterGetGroupMembershipCallback(apCommandObj, aCommandPath, commandData); + } + break; + } + case Commands::RemoveGroup::Id: { + Commands::RemoveGroup::DecodableType commandData; + TLVError = DataModel::Decode(aDataTlv, commandData); + if (TLVError == CHIP_NO_ERROR) + { + wasHandled = emberAfGroupsClusterRemoveGroupCallback(apCommandObj, aCommandPath, commandData); + } + break; + } + case Commands::RemoveAllGroups::Id: { + Commands::RemoveAllGroups::DecodableType commandData; + TLVError = DataModel::Decode(aDataTlv, commandData); + if (TLVError == CHIP_NO_ERROR) + { + wasHandled = emberAfGroupsClusterRemoveAllGroupsCallback(apCommandObj, aCommandPath, commandData); + } + break; + } + case Commands::AddGroupIfIdentifying::Id: { + Commands::AddGroupIfIdentifying::DecodableType commandData; + TLVError = DataModel::Decode(aDataTlv, commandData); + if (TLVError == CHIP_NO_ERROR) + { + wasHandled = emberAfGroupsClusterAddGroupIfIdentifyingCallback(apCommandObj, aCommandPath, commandData); + } + break; + } + default: { + // Unrecognized command ID, error status will apply. + apCommandObj->AddStatus(aCommandPath, Protocols::InteractionModel::Status::UnsupportedCommand); + ChipLogError(Zcl, "Unknown command " ChipLogFormatMEI " for cluster " ChipLogFormatMEI, + ChipLogValueMEI(aCommandPath.mCommandId), ChipLogValueMEI(aCommandPath.mClusterId)); + return; + } + } + } + + if (CHIP_NO_ERROR != TLVError || !wasHandled) + { + apCommandObj->AddStatus(aCommandPath, Protocols::InteractionModel::Status::InvalidCommand); + ChipLogProgress(Zcl, "Failed to dispatch command, TLVError=%" CHIP_ERROR_FORMAT, TLVError.Format()); + } +} + +} // namespace Groups + +namespace Identify { + +void DispatchServerCommand(CommandHandler * apCommandObj, const ConcreteCommandPath & aCommandPath, TLV::TLVReader & aDataTlv) +{ + CHIP_ERROR TLVError = CHIP_NO_ERROR; + bool wasHandled = false; + { + switch (aCommandPath.mCommandId) + { + case Commands::Identify::Id: { + Commands::Identify::DecodableType commandData; + TLVError = DataModel::Decode(aDataTlv, commandData); + if (TLVError == CHIP_NO_ERROR) + { + wasHandled = emberAfIdentifyClusterIdentifyCallback(apCommandObj, aCommandPath, commandData); + } + break; + } + case Commands::TriggerEffect::Id: { + Commands::TriggerEffect::DecodableType commandData; + TLVError = DataModel::Decode(aDataTlv, commandData); + if (TLVError == CHIP_NO_ERROR) + { + wasHandled = emberAfIdentifyClusterTriggerEffectCallback(apCommandObj, aCommandPath, commandData); + } + break; + } + default: { + // Unrecognized command ID, error status will apply. + apCommandObj->AddStatus(aCommandPath, Protocols::InteractionModel::Status::UnsupportedCommand); + ChipLogError(Zcl, "Unknown command " ChipLogFormatMEI " for cluster " ChipLogFormatMEI, + ChipLogValueMEI(aCommandPath.mCommandId), ChipLogValueMEI(aCommandPath.mClusterId)); + return; + } + } + } + + if (CHIP_NO_ERROR != TLVError || !wasHandled) + { + apCommandObj->AddStatus(aCommandPath, Protocols::InteractionModel::Status::InvalidCommand); + ChipLogProgress(Zcl, "Failed to dispatch command, TLVError=%" CHIP_ERROR_FORMAT, TLVError.Format()); + } +} + +} // namespace Identify + +namespace NetworkCommissioning { + +void DispatchServerCommand(CommandHandler * apCommandObj, const ConcreteCommandPath & aCommandPath, TLV::TLVReader & aDataTlv) +{ + CHIP_ERROR TLVError = CHIP_NO_ERROR; + bool wasHandled = false; + { + switch (aCommandPath.mCommandId) + { + case Commands::ScanNetworks::Id: { + Commands::ScanNetworks::DecodableType commandData; + TLVError = DataModel::Decode(aDataTlv, commandData); + if (TLVError == CHIP_NO_ERROR) + { + wasHandled = emberAfNetworkCommissioningClusterScanNetworksCallback(apCommandObj, aCommandPath, commandData); + } + break; + } + case Commands::AddOrUpdateWiFiNetwork::Id: { + Commands::AddOrUpdateWiFiNetwork::DecodableType commandData; + TLVError = DataModel::Decode(aDataTlv, commandData); + if (TLVError == CHIP_NO_ERROR) + { + wasHandled = + emberAfNetworkCommissioningClusterAddOrUpdateWiFiNetworkCallback(apCommandObj, aCommandPath, commandData); + } + break; + } + case Commands::AddOrUpdateThreadNetwork::Id: { + Commands::AddOrUpdateThreadNetwork::DecodableType commandData; + TLVError = DataModel::Decode(aDataTlv, commandData); + if (TLVError == CHIP_NO_ERROR) + { + wasHandled = + emberAfNetworkCommissioningClusterAddOrUpdateThreadNetworkCallback(apCommandObj, aCommandPath, commandData); + } + break; + } + case Commands::RemoveNetwork::Id: { + Commands::RemoveNetwork::DecodableType commandData; + TLVError = DataModel::Decode(aDataTlv, commandData); + if (TLVError == CHIP_NO_ERROR) + { + wasHandled = emberAfNetworkCommissioningClusterRemoveNetworkCallback(apCommandObj, aCommandPath, commandData); + } + break; + } + case Commands::ConnectNetwork::Id: { + Commands::ConnectNetwork::DecodableType commandData; + TLVError = DataModel::Decode(aDataTlv, commandData); + if (TLVError == CHIP_NO_ERROR) + { + wasHandled = emberAfNetworkCommissioningClusterConnectNetworkCallback(apCommandObj, aCommandPath, commandData); + } + break; + } + case Commands::ReorderNetwork::Id: { + Commands::ReorderNetwork::DecodableType commandData; + TLVError = DataModel::Decode(aDataTlv, commandData); + if (TLVError == CHIP_NO_ERROR) + { + wasHandled = emberAfNetworkCommissioningClusterReorderNetworkCallback(apCommandObj, aCommandPath, commandData); + } + break; + } + default: { + // Unrecognized command ID, error status will apply. + apCommandObj->AddStatus(aCommandPath, Protocols::InteractionModel::Status::UnsupportedCommand); + ChipLogError(Zcl, "Unknown command " ChipLogFormatMEI " for cluster " ChipLogFormatMEI, + ChipLogValueMEI(aCommandPath.mCommandId), ChipLogValueMEI(aCommandPath.mClusterId)); + return; + } + } + } + + if (CHIP_NO_ERROR != TLVError || !wasHandled) + { + apCommandObj->AddStatus(aCommandPath, Protocols::InteractionModel::Status::InvalidCommand); + ChipLogProgress(Zcl, "Failed to dispatch command, TLVError=%" CHIP_ERROR_FORMAT, TLVError.Format()); + } +} + +} // namespace NetworkCommissioning + +namespace OtaSoftwareUpdateRequestor { + +void DispatchServerCommand(CommandHandler * apCommandObj, const ConcreteCommandPath & aCommandPath, TLV::TLVReader & aDataTlv) +{ + CHIP_ERROR TLVError = CHIP_NO_ERROR; + bool wasHandled = false; + { + switch (aCommandPath.mCommandId) + { + case Commands::AnnounceOtaProvider::Id: { + Commands::AnnounceOtaProvider::DecodableType commandData; + TLVError = DataModel::Decode(aDataTlv, commandData); + if (TLVError == CHIP_NO_ERROR) + { + wasHandled = + emberAfOtaSoftwareUpdateRequestorClusterAnnounceOtaProviderCallback(apCommandObj, aCommandPath, commandData); + } + break; + } + default: { + // Unrecognized command ID, error status will apply. + apCommandObj->AddStatus(aCommandPath, Protocols::InteractionModel::Status::UnsupportedCommand); + ChipLogError(Zcl, "Unknown command " ChipLogFormatMEI " for cluster " ChipLogFormatMEI, + ChipLogValueMEI(aCommandPath.mCommandId), ChipLogValueMEI(aCommandPath.mClusterId)); + return; + } + } + } + + if (CHIP_NO_ERROR != TLVError || !wasHandled) + { + apCommandObj->AddStatus(aCommandPath, Protocols::InteractionModel::Status::InvalidCommand); + ChipLogProgress(Zcl, "Failed to dispatch command, TLVError=%" CHIP_ERROR_FORMAT, TLVError.Format()); + } +} + +} // namespace OtaSoftwareUpdateRequestor + +namespace OperationalCredentials { + +void DispatchServerCommand(CommandHandler * apCommandObj, const ConcreteCommandPath & aCommandPath, TLV::TLVReader & aDataTlv) +{ + CHIP_ERROR TLVError = CHIP_NO_ERROR; + bool wasHandled = false; + { + switch (aCommandPath.mCommandId) + { + case Commands::AttestationRequest::Id: { + Commands::AttestationRequest::DecodableType commandData; + TLVError = DataModel::Decode(aDataTlv, commandData); + if (TLVError == CHIP_NO_ERROR) + { + wasHandled = + emberAfOperationalCredentialsClusterAttestationRequestCallback(apCommandObj, aCommandPath, commandData); + } + break; + } + case Commands::CertificateChainRequest::Id: { + Commands::CertificateChainRequest::DecodableType commandData; + TLVError = DataModel::Decode(aDataTlv, commandData); + if (TLVError == CHIP_NO_ERROR) + { + wasHandled = + emberAfOperationalCredentialsClusterCertificateChainRequestCallback(apCommandObj, aCommandPath, commandData); + } + break; + } + case Commands::CSRRequest::Id: { + Commands::CSRRequest::DecodableType commandData; + TLVError = DataModel::Decode(aDataTlv, commandData); + if (TLVError == CHIP_NO_ERROR) + { + wasHandled = emberAfOperationalCredentialsClusterCSRRequestCallback(apCommandObj, aCommandPath, commandData); + } + break; + } + case Commands::AddNOC::Id: { + Commands::AddNOC::DecodableType commandData; + TLVError = DataModel::Decode(aDataTlv, commandData); + if (TLVError == CHIP_NO_ERROR) + { + wasHandled = emberAfOperationalCredentialsClusterAddNOCCallback(apCommandObj, aCommandPath, commandData); + } + break; + } + case Commands::UpdateNOC::Id: { + Commands::UpdateNOC::DecodableType commandData; + TLVError = DataModel::Decode(aDataTlv, commandData); + if (TLVError == CHIP_NO_ERROR) + { + wasHandled = emberAfOperationalCredentialsClusterUpdateNOCCallback(apCommandObj, aCommandPath, commandData); + } + break; + } + case Commands::UpdateFabricLabel::Id: { + Commands::UpdateFabricLabel::DecodableType commandData; + TLVError = DataModel::Decode(aDataTlv, commandData); + if (TLVError == CHIP_NO_ERROR) + { + wasHandled = emberAfOperationalCredentialsClusterUpdateFabricLabelCallback(apCommandObj, aCommandPath, commandData); + } + break; + } + case Commands::RemoveFabric::Id: { + Commands::RemoveFabric::DecodableType commandData; + TLVError = DataModel::Decode(aDataTlv, commandData); + if (TLVError == CHIP_NO_ERROR) + { + wasHandled = emberAfOperationalCredentialsClusterRemoveFabricCallback(apCommandObj, aCommandPath, commandData); + } + break; + } + case Commands::AddTrustedRootCertificate::Id: { + Commands::AddTrustedRootCertificate::DecodableType commandData; + TLVError = DataModel::Decode(aDataTlv, commandData); + if (TLVError == CHIP_NO_ERROR) + { + wasHandled = + emberAfOperationalCredentialsClusterAddTrustedRootCertificateCallback(apCommandObj, aCommandPath, commandData); + } + break; + } + default: { + // Unrecognized command ID, error status will apply. + apCommandObj->AddStatus(aCommandPath, Protocols::InteractionModel::Status::UnsupportedCommand); + ChipLogError(Zcl, "Unknown command " ChipLogFormatMEI " for cluster " ChipLogFormatMEI, + ChipLogValueMEI(aCommandPath.mCommandId), ChipLogValueMEI(aCommandPath.mClusterId)); + return; + } + } + } + + if (CHIP_NO_ERROR != TLVError || !wasHandled) + { + apCommandObj->AddStatus(aCommandPath, Protocols::InteractionModel::Status::InvalidCommand); + ChipLogProgress(Zcl, "Failed to dispatch command, TLVError=%" CHIP_ERROR_FORMAT, TLVError.Format()); + } +} + +} // namespace OperationalCredentials + +namespace SoftwareDiagnostics { + +void DispatchServerCommand(CommandHandler * apCommandObj, const ConcreteCommandPath & aCommandPath, TLV::TLVReader & aDataTlv) +{ + CHIP_ERROR TLVError = CHIP_NO_ERROR; + bool wasHandled = false; + { + switch (aCommandPath.mCommandId) + { + case Commands::ResetWatermarks::Id: { + Commands::ResetWatermarks::DecodableType commandData; + TLVError = DataModel::Decode(aDataTlv, commandData); + if (TLVError == CHIP_NO_ERROR) + { + wasHandled = emberAfSoftwareDiagnosticsClusterResetWatermarksCallback(apCommandObj, aCommandPath, commandData); + } + break; + } + default: { + // Unrecognized command ID, error status will apply. + apCommandObj->AddStatus(aCommandPath, Protocols::InteractionModel::Status::UnsupportedCommand); + ChipLogError(Zcl, "Unknown command " ChipLogFormatMEI " for cluster " ChipLogFormatMEI, + ChipLogValueMEI(aCommandPath.mCommandId), ChipLogValueMEI(aCommandPath.mClusterId)); + return; + } + } + } + + if (CHIP_NO_ERROR != TLVError || !wasHandled) + { + apCommandObj->AddStatus(aCommandPath, Protocols::InteractionModel::Status::InvalidCommand); + ChipLogProgress(Zcl, "Failed to dispatch command, TLVError=%" CHIP_ERROR_FORMAT, TLVError.Format()); + } +} + +} // namespace SoftwareDiagnostics + +namespace ThreadNetworkDiagnostics { + +void DispatchServerCommand(CommandHandler * apCommandObj, const ConcreteCommandPath & aCommandPath, TLV::TLVReader & aDataTlv) +{ + CHIP_ERROR TLVError = CHIP_NO_ERROR; + bool wasHandled = false; + { + switch (aCommandPath.mCommandId) + { + case Commands::ResetCounts::Id: { + Commands::ResetCounts::DecodableType commandData; + TLVError = DataModel::Decode(aDataTlv, commandData); + if (TLVError == CHIP_NO_ERROR) + { + wasHandled = emberAfThreadNetworkDiagnosticsClusterResetCountsCallback(apCommandObj, aCommandPath, commandData); + } + break; + } + default: { + // Unrecognized command ID, error status will apply. + apCommandObj->AddStatus(aCommandPath, Protocols::InteractionModel::Status::UnsupportedCommand); + ChipLogError(Zcl, "Unknown command " ChipLogFormatMEI " for cluster " ChipLogFormatMEI, + ChipLogValueMEI(aCommandPath.mCommandId), ChipLogValueMEI(aCommandPath.mClusterId)); + return; + } + } + } + + if (CHIP_NO_ERROR != TLVError || !wasHandled) + { + apCommandObj->AddStatus(aCommandPath, Protocols::InteractionModel::Status::InvalidCommand); + ChipLogProgress(Zcl, "Failed to dispatch command, TLVError=%" CHIP_ERROR_FORMAT, TLVError.Format()); + } +} + +} // namespace ThreadNetworkDiagnostics + +namespace WiFiNetworkDiagnostics { + +void DispatchServerCommand(CommandHandler * apCommandObj, const ConcreteCommandPath & aCommandPath, TLV::TLVReader & aDataTlv) +{ + CHIP_ERROR TLVError = CHIP_NO_ERROR; + bool wasHandled = false; + { + switch (aCommandPath.mCommandId) + { + case Commands::ResetCounts::Id: { + Commands::ResetCounts::DecodableType commandData; + TLVError = DataModel::Decode(aDataTlv, commandData); + if (TLVError == CHIP_NO_ERROR) + { + wasHandled = emberAfWiFiNetworkDiagnosticsClusterResetCountsCallback(apCommandObj, aCommandPath, commandData); + } + break; + } + default: { + // Unrecognized command ID, error status will apply. + apCommandObj->AddStatus(aCommandPath, Protocols::InteractionModel::Status::UnsupportedCommand); + ChipLogError(Zcl, "Unknown command " ChipLogFormatMEI " for cluster " ChipLogFormatMEI, + ChipLogValueMEI(aCommandPath.mCommandId), ChipLogValueMEI(aCommandPath.mClusterId)); + return; + } + } + } + + if (CHIP_NO_ERROR != TLVError || !wasHandled) + { + apCommandObj->AddStatus(aCommandPath, Protocols::InteractionModel::Status::InvalidCommand); + ChipLogProgress(Zcl, "Failed to dispatch command, TLVError=%" CHIP_ERROR_FORMAT, TLVError.Format()); + } +} + +} // namespace WiFiNetworkDiagnostics + +} // namespace Clusters + +void DispatchSingleClusterCommand(const ConcreteCommandPath & aCommandPath, TLV::TLVReader & aReader, CommandHandler * apCommandObj) +{ + Compatibility::SetupEmberAfCommandHandler(apCommandObj, aCommandPath); + + switch (aCommandPath.mClusterId) + { + case Clusters::AdministratorCommissioning::Id: + Clusters::AdministratorCommissioning::DispatchServerCommand(apCommandObj, aCommandPath, aReader); + break; + case Clusters::DiagnosticLogs::Id: + Clusters::DiagnosticLogs::DispatchServerCommand(apCommandObj, aCommandPath, aReader); + break; + case Clusters::EthernetNetworkDiagnostics::Id: + Clusters::EthernetNetworkDiagnostics::DispatchServerCommand(apCommandObj, aCommandPath, aReader); + break; + case Clusters::GeneralCommissioning::Id: + Clusters::GeneralCommissioning::DispatchServerCommand(apCommandObj, aCommandPath, aReader); + break; + case Clusters::GeneralDiagnostics::Id: + Clusters::GeneralDiagnostics::DispatchServerCommand(apCommandObj, aCommandPath, aReader); + break; + case Clusters::GroupKeyManagement::Id: + Clusters::GroupKeyManagement::DispatchServerCommand(apCommandObj, aCommandPath, aReader); + break; + case Clusters::Groups::Id: + Clusters::Groups::DispatchServerCommand(apCommandObj, aCommandPath, aReader); + break; + case Clusters::Identify::Id: + Clusters::Identify::DispatchServerCommand(apCommandObj, aCommandPath, aReader); + break; + case Clusters::NetworkCommissioning::Id: + Clusters::NetworkCommissioning::DispatchServerCommand(apCommandObj, aCommandPath, aReader); + break; + case Clusters::OtaSoftwareUpdateRequestor::Id: + Clusters::OtaSoftwareUpdateRequestor::DispatchServerCommand(apCommandObj, aCommandPath, aReader); + break; + case Clusters::OperationalCredentials::Id: + Clusters::OperationalCredentials::DispatchServerCommand(apCommandObj, aCommandPath, aReader); + break; + case Clusters::SoftwareDiagnostics::Id: + Clusters::SoftwareDiagnostics::DispatchServerCommand(apCommandObj, aCommandPath, aReader); + break; + case Clusters::ThreadNetworkDiagnostics::Id: + Clusters::ThreadNetworkDiagnostics::DispatchServerCommand(apCommandObj, aCommandPath, aReader); + break; + case Clusters::WiFiNetworkDiagnostics::Id: + Clusters::WiFiNetworkDiagnostics::DispatchServerCommand(apCommandObj, aCommandPath, aReader); + break; + default: + ChipLogError(Zcl, "Unknown cluster " ChipLogFormatMEI, ChipLogValueMEI(aCommandPath.mClusterId)); + apCommandObj->AddStatus(aCommandPath, Protocols::InteractionModel::Status::UnsupportedCluster); + break; + } + + Compatibility::ResetEmberAfObjects(); +} + +} // namespace app +} // namespace chip diff --git a/zzz_generated/contact-sensor-app/zap-generated/PluginApplicationCallbacks.h b/zzz_generated/contact-sensor-app/zap-generated/PluginApplicationCallbacks.h new file mode 100644 index 00000000000000..70685cfb3b2ee4 --- /dev/null +++ b/zzz_generated/contact-sensor-app/zap-generated/PluginApplicationCallbacks.h @@ -0,0 +1,48 @@ +/* + * + * 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 + +#pragma once + +#include + +#define MATTER_PLUGINS_INIT \ + MatterIdentifyPluginServerInitCallback(); \ + MatterGroupsPluginServerInitCallback(); \ + MatterDescriptorPluginServerInitCallback(); \ + MatterAccessControlPluginServerInitCallback(); \ + MatterBasicPluginServerInitCallback(); \ + MatterOtaSoftwareUpdateProviderPluginClientInitCallback(); \ + MatterOtaSoftwareUpdateRequestorPluginServerInitCallback(); \ + MatterLocalizationConfigurationPluginServerInitCallback(); \ + MatterTimeFormatLocalizationPluginServerInitCallback(); \ + MatterGeneralCommissioningPluginServerInitCallback(); \ + MatterNetworkCommissioningPluginServerInitCallback(); \ + MatterDiagnosticLogsPluginServerInitCallback(); \ + MatterGeneralDiagnosticsPluginServerInitCallback(); \ + MatterSoftwareDiagnosticsPluginServerInitCallback(); \ + MatterThreadNetworkDiagnosticsPluginServerInitCallback(); \ + MatterWiFiNetworkDiagnosticsPluginServerInitCallback(); \ + MatterEthernetNetworkDiagnosticsPluginServerInitCallback(); \ + MatterAdministratorCommissioningPluginServerInitCallback(); \ + MatterOperationalCredentialsPluginServerInitCallback(); \ + MatterGroupKeyManagementPluginServerInitCallback(); \ + MatterFixedLabelPluginServerInitCallback(); \ + MatterUserLabelPluginServerInitCallback(); \ + MatterBooleanStatePluginServerInitCallback(); \ + MatterOccupancySensingPluginServerInitCallback(); diff --git a/zzz_generated/contact-sensor-app/zap-generated/access.h b/zzz_generated/contact-sensor-app/zap-generated/access.h new file mode 100644 index 00000000000000..0386dfe564b3f7 --- /dev/null +++ b/zzz_generated/contact-sensor-app/zap-generated/access.h @@ -0,0 +1,266 @@ +/* + * + * 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 + +// Prevent multiple inclusion +#pragma once + +#include + +// Prevent changing generated format +// clang-format off + +//////////////////////////////////////////////////////////////////////////////// + +// Parallel array data (*cluster*, attribute, privilege) for read attribute +#define GENERATED_ACCESS_READ_ATTRIBUTE__CLUSTER { \ + 31, /* Cluster: Access Control, Attribute: ACL, Privilege: administer */ \ + 31, /* Cluster: Access Control, Attribute: Extension, Privilege: administer */ \ + /* Cluster: Access Control, Attribute: SubjectsPerAccessControlEntry, Privilege: view */ \ + /* Cluster: Access Control, Attribute: TargetsPerAccessControlEntry, Privilege: view */ \ + /* Cluster: Access Control, Attribute: AccessControlEntriesPerFabric, Privilege: view */ \ + /* Cluster: Basic, Attribute: NodeLabel, Privilege: view */ \ + /* Cluster: Basic, Attribute: Location, Privilege: view */ \ + /* Cluster: Basic, Attribute: LocalConfigDisabled, Privilege: view */ \ + /* Cluster: General Commissioning, Attribute: Breadcrumb, Privilege: view */ \ + 49, /* Cluster: Network Commissioning, Attribute: MaxNetworks, Privilege: administer */ \ + 49, /* Cluster: Network Commissioning, Attribute: Networks, Privilege: administer */ \ + /* Cluster: Network Commissioning, Attribute: InterfaceEnabled, Privilege: view */ \ + 49, /* Cluster: Network Commissioning, Attribute: LastNetworkingStatus, Privilege: administer */ \ + 49, /* Cluster: Network Commissioning, Attribute: LastNetworkID, Privilege: administer */ \ + 49, /* Cluster: Network Commissioning, Attribute: LastConnectErrorValue, Privilege: administer */ \ + 62, /* Cluster: Operational Credentials, Attribute: NOCs, Privilege: administer */ \ + /* Cluster: Group Key Management, Attribute: GroupKeyMap, Privilege: view */ \ + /* Cluster: User Label, Attribute: label list, Privilege: view */ \ +} + +// Parallel array data (cluster, *attribute*, privilege) for read attribute +#define GENERATED_ACCESS_READ_ATTRIBUTE__ATTRIBUTE { \ + 0, /* Cluster: Access Control, Attribute: ACL, Privilege: administer */ \ + 1, /* Cluster: Access Control, Attribute: Extension, Privilege: administer */ \ + /* Cluster: Access Control, Attribute: SubjectsPerAccessControlEntry, Privilege: view */ \ + /* Cluster: Access Control, Attribute: TargetsPerAccessControlEntry, Privilege: view */ \ + /* Cluster: Access Control, Attribute: AccessControlEntriesPerFabric, Privilege: view */ \ + /* Cluster: Basic, Attribute: NodeLabel, Privilege: view */ \ + /* Cluster: Basic, Attribute: Location, Privilege: view */ \ + /* Cluster: Basic, Attribute: LocalConfigDisabled, Privilege: view */ \ + /* Cluster: General Commissioning, Attribute: Breadcrumb, Privilege: view */ \ + 0, /* Cluster: Network Commissioning, Attribute: MaxNetworks, Privilege: administer */ \ + 1, /* Cluster: Network Commissioning, Attribute: Networks, Privilege: administer */ \ + /* Cluster: Network Commissioning, Attribute: InterfaceEnabled, Privilege: view */ \ + 5, /* Cluster: Network Commissioning, Attribute: LastNetworkingStatus, Privilege: administer */ \ + 6, /* Cluster: Network Commissioning, Attribute: LastNetworkID, Privilege: administer */ \ + 7, /* Cluster: Network Commissioning, Attribute: LastConnectErrorValue, Privilege: administer */ \ + 0, /* Cluster: Operational Credentials, Attribute: NOCs, Privilege: administer */ \ + /* Cluster: Group Key Management, Attribute: GroupKeyMap, Privilege: view */ \ + /* Cluster: User Label, Attribute: label list, Privilege: view */ \ +} + +// Parallel array data (cluster, attribute, *privilege*) for read attribute +#define GENERATED_ACCESS_READ_ATTRIBUTE__PRIVILEGE { \ + kMatterAccessPrivilegeAdminister, /* Cluster: Access Control, Attribute: ACL, Privilege: administer */ \ + kMatterAccessPrivilegeAdminister, /* Cluster: Access Control, Attribute: Extension, Privilege: administer */ \ + /* Cluster: Access Control, Attribute: SubjectsPerAccessControlEntry, Privilege: view */ \ + /* Cluster: Access Control, Attribute: TargetsPerAccessControlEntry, Privilege: view */ \ + /* Cluster: Access Control, Attribute: AccessControlEntriesPerFabric, Privilege: view */ \ + /* Cluster: Basic, Attribute: NodeLabel, Privilege: view */ \ + /* Cluster: Basic, Attribute: Location, Privilege: view */ \ + /* Cluster: Basic, Attribute: LocalConfigDisabled, Privilege: view */ \ + /* Cluster: General Commissioning, Attribute: Breadcrumb, Privilege: view */ \ + kMatterAccessPrivilegeAdminister, /* Cluster: Network Commissioning, Attribute: MaxNetworks, Privilege: administer */ \ + kMatterAccessPrivilegeAdminister, /* Cluster: Network Commissioning, Attribute: Networks, Privilege: administer */ \ + /* Cluster: Network Commissioning, Attribute: InterfaceEnabled, Privilege: view */ \ + kMatterAccessPrivilegeAdminister, /* Cluster: Network Commissioning, Attribute: LastNetworkingStatus, Privilege: administer */ \ + kMatterAccessPrivilegeAdminister, /* Cluster: Network Commissioning, Attribute: LastNetworkID, Privilege: administer */ \ + kMatterAccessPrivilegeAdminister, /* Cluster: Network Commissioning, Attribute: LastConnectErrorValue, Privilege: administer */ \ + kMatterAccessPrivilegeAdminister, /* Cluster: Operational Credentials, Attribute: NOCs, Privilege: administer */ \ + /* Cluster: Group Key Management, Attribute: GroupKeyMap, Privilege: view */ \ + /* Cluster: User Label, Attribute: label list, Privilege: view */ \ +} + +//////////////////////////////////////////////////////////////////////////////// + +// Parallel array data (*cluster*, attribute, privilege) for write attribute +#define GENERATED_ACCESS_WRITE_ATTRIBUTE__CLUSTER { \ + 31, /* Cluster: Access Control, Attribute: ACL, Privilege: administer */ \ + 31, /* Cluster: Access Control, Attribute: Extension, Privilege: administer */ \ + 40, /* Cluster: Basic, Attribute: NodeLabel, Privilege: manage */ \ + 40, /* Cluster: Basic, Attribute: Location, Privilege: administer */ \ + 40, /* Cluster: Basic, Attribute: LocalConfigDisabled, Privilege: manage */ \ + 48, /* Cluster: General Commissioning, Attribute: Breadcrumb, Privilege: administer */ \ + 49, /* Cluster: Network Commissioning, Attribute: InterfaceEnabled, Privilege: administer */ \ + 63, /* Cluster: Group Key Management, Attribute: GroupKeyMap, Privilege: manage */ \ + 65, /* Cluster: User Label, Attribute: label list, Privilege: manage */ \ +} + +// Parallel array data (cluster, *attribute*, privilege) for write attribute +#define GENERATED_ACCESS_WRITE_ATTRIBUTE__ATTRIBUTE { \ + 0, /* Cluster: Access Control, Attribute: ACL, Privilege: administer */ \ + 1, /* Cluster: Access Control, Attribute: Extension, Privilege: administer */ \ + 5, /* Cluster: Basic, Attribute: NodeLabel, Privilege: manage */ \ + 6, /* Cluster: Basic, Attribute: Location, Privilege: administer */ \ + 16, /* Cluster: Basic, Attribute: LocalConfigDisabled, Privilege: manage */ \ + 0, /* Cluster: General Commissioning, Attribute: Breadcrumb, Privilege: administer */ \ + 4, /* Cluster: Network Commissioning, Attribute: InterfaceEnabled, Privilege: administer */ \ + 0, /* Cluster: Group Key Management, Attribute: GroupKeyMap, Privilege: manage */ \ + 0, /* Cluster: User Label, Attribute: label list, Privilege: manage */ \ +} + +// Parallel array data (cluster, attribute, *privilege*) for write attribute +#define GENERATED_ACCESS_WRITE_ATTRIBUTE__PRIVILEGE { \ + kMatterAccessPrivilegeAdminister, /* Cluster: Access Control, Attribute: ACL, Privilege: administer */ \ + kMatterAccessPrivilegeAdminister, /* Cluster: Access Control, Attribute: Extension, Privilege: administer */ \ + kMatterAccessPrivilegeManage, /* Cluster: Basic, Attribute: NodeLabel, Privilege: manage */ \ + kMatterAccessPrivilegeAdminister, /* Cluster: Basic, Attribute: Location, Privilege: administer */ \ + kMatterAccessPrivilegeManage, /* Cluster: Basic, Attribute: LocalConfigDisabled, Privilege: manage */ \ + kMatterAccessPrivilegeAdminister, /* Cluster: General Commissioning, Attribute: Breadcrumb, Privilege: administer */ \ + kMatterAccessPrivilegeAdminister, /* Cluster: Network Commissioning, Attribute: InterfaceEnabled, Privilege: administer */ \ + kMatterAccessPrivilegeManage, /* Cluster: Group Key Management, Attribute: GroupKeyMap, Privilege: manage */ \ + kMatterAccessPrivilegeManage, /* Cluster: User Label, Attribute: label list, Privilege: manage */ \ +} + +//////////////////////////////////////////////////////////////////////////////// + +// Parallel array data (*cluster*, command, privilege) for invoke command +#define GENERATED_ACCESS_INVOKE_COMMAND__CLUSTER { \ + 3, /* Cluster: Identify, Command: Identify, Privilege: manage */ \ + 3, /* Cluster: Identify, Command: TriggerEffect, Privilege: manage */ \ + 4, /* Cluster: Groups, Command: AddGroup, Privilege: manage */ \ + 4, /* Cluster: Groups, Command: RemoveGroup, Privilege: manage */ \ + 4, /* Cluster: Groups, Command: RemoveAllGroups, Privilege: manage */ \ + 4, /* Cluster: Groups, Command: AddGroupIfIdentifying, Privilege: manage */ \ + 48, /* Cluster: General Commissioning, Command: ArmFailSafe, Privilege: administer */ \ + 48, /* Cluster: General Commissioning, Command: SetRegulatoryConfig, Privilege: administer */ \ + 48, /* Cluster: General Commissioning, Command: CommissioningComplete, Privilege: administer */ \ + 49, /* Cluster: Network Commissioning, Command: ScanNetworks, Privilege: administer */ \ + 49, /* Cluster: Network Commissioning, Command: AddOrUpdateWiFiNetwork, Privilege: administer */ \ + 49, /* Cluster: Network Commissioning, Command: AddOrUpdateThreadNetwork, Privilege: administer */ \ + 49, /* Cluster: Network Commissioning, Command: RemoveNetwork, Privilege: administer */ \ + 49, /* Cluster: Network Commissioning, Command: ConnectNetwork, Privilege: administer */ \ + 49, /* Cluster: Network Commissioning, Command: ReorderNetwork, Privilege: administer */ \ + 51, /* Cluster: General Diagnostics, Command: TestEventTrigger, Privilege: manage */ \ + 60, /* Cluster: AdministratorCommissioning, Command: OpenCommissioningWindow, Privilege: administer */ \ + 60, /* Cluster: AdministratorCommissioning, Command: OpenBasicCommissioningWindow, Privilege: administer */ \ + 60, /* Cluster: AdministratorCommissioning, Command: RevokeCommissioning, Privilege: administer */ \ + 62, /* Cluster: Operational Credentials, Command: AttestationRequest, Privilege: administer */ \ + 62, /* Cluster: Operational Credentials, Command: CertificateChainRequest, Privilege: administer */ \ + 62, /* Cluster: Operational Credentials, Command: CSRRequest, Privilege: administer */ \ + 62, /* Cluster: Operational Credentials, Command: AddNOC, Privilege: administer */ \ + 62, /* Cluster: Operational Credentials, Command: UpdateNOC, Privilege: administer */ \ + 62, /* Cluster: Operational Credentials, Command: UpdateFabricLabel, Privilege: administer */ \ + 62, /* Cluster: Operational Credentials, Command: RemoveFabric, Privilege: administer */ \ + 62, /* Cluster: Operational Credentials, Command: AddTrustedRootCertificate, Privilege: administer */ \ + 63, /* Cluster: Group Key Management, Command: KeySetWrite, Privilege: administer */ \ + 63, /* Cluster: Group Key Management, Command: KeySetRead, Privilege: administer */ \ + 63, /* Cluster: Group Key Management, Command: KeySetRemove, Privilege: administer */ \ + 63, /* Cluster: Group Key Management, Command: KeySetReadAllIndices, Privilege: administer */ \ +} + +// Parallel array data (cluster, *command*, privilege) for invoke command +#define GENERATED_ACCESS_INVOKE_COMMAND__COMMAND { \ + 0, /* Cluster: Identify, Command: Identify, Privilege: manage */ \ + 64, /* Cluster: Identify, Command: TriggerEffect, Privilege: manage */ \ + 0, /* Cluster: Groups, Command: AddGroup, Privilege: manage */ \ + 3, /* Cluster: Groups, Command: RemoveGroup, Privilege: manage */ \ + 4, /* Cluster: Groups, Command: RemoveAllGroups, Privilege: manage */ \ + 5, /* Cluster: Groups, Command: AddGroupIfIdentifying, Privilege: manage */ \ + 0, /* Cluster: General Commissioning, Command: ArmFailSafe, Privilege: administer */ \ + 2, /* Cluster: General Commissioning, Command: SetRegulatoryConfig, Privilege: administer */ \ + 4, /* Cluster: General Commissioning, Command: CommissioningComplete, Privilege: administer */ \ + 0, /* Cluster: Network Commissioning, Command: ScanNetworks, Privilege: administer */ \ + 2, /* Cluster: Network Commissioning, Command: AddOrUpdateWiFiNetwork, Privilege: administer */ \ + 3, /* Cluster: Network Commissioning, Command: AddOrUpdateThreadNetwork, Privilege: administer */ \ + 4, /* Cluster: Network Commissioning, Command: RemoveNetwork, Privilege: administer */ \ + 6, /* Cluster: Network Commissioning, Command: ConnectNetwork, Privilege: administer */ \ + 8, /* Cluster: Network Commissioning, Command: ReorderNetwork, Privilege: administer */ \ + 0, /* Cluster: General Diagnostics, Command: TestEventTrigger, Privilege: manage */ \ + 0, /* Cluster: AdministratorCommissioning, Command: OpenCommissioningWindow, Privilege: administer */ \ + 1, /* Cluster: AdministratorCommissioning, Command: OpenBasicCommissioningWindow, Privilege: administer */ \ + 2, /* Cluster: AdministratorCommissioning, Command: RevokeCommissioning, Privilege: administer */ \ + 0, /* Cluster: Operational Credentials, Command: AttestationRequest, Privilege: administer */ \ + 2, /* Cluster: Operational Credentials, Command: CertificateChainRequest, Privilege: administer */ \ + 4, /* Cluster: Operational Credentials, Command: CSRRequest, Privilege: administer */ \ + 6, /* Cluster: Operational Credentials, Command: AddNOC, Privilege: administer */ \ + 7, /* Cluster: Operational Credentials, Command: UpdateNOC, Privilege: administer */ \ + 9, /* Cluster: Operational Credentials, Command: UpdateFabricLabel, Privilege: administer */ \ + 10, /* Cluster: Operational Credentials, Command: RemoveFabric, Privilege: administer */ \ + 11, /* Cluster: Operational Credentials, Command: AddTrustedRootCertificate, Privilege: administer */ \ + 0, /* Cluster: Group Key Management, Command: KeySetWrite, Privilege: administer */ \ + 1, /* Cluster: Group Key Management, Command: KeySetRead, Privilege: administer */ \ + 3, /* Cluster: Group Key Management, Command: KeySetRemove, Privilege: administer */ \ + 4, /* Cluster: Group Key Management, Command: KeySetReadAllIndices, Privilege: administer */ \ +} + +// Parallel array data (cluster, command, *privilege*) for invoke command +#define GENERATED_ACCESS_INVOKE_COMMAND__PRIVILEGE { \ + kMatterAccessPrivilegeManage, /* Cluster: Identify, Command: Identify, Privilege: manage */ \ + kMatterAccessPrivilegeManage, /* Cluster: Identify, Command: TriggerEffect, Privilege: manage */ \ + kMatterAccessPrivilegeManage, /* Cluster: Groups, Command: AddGroup, Privilege: manage */ \ + kMatterAccessPrivilegeManage, /* Cluster: Groups, Command: RemoveGroup, Privilege: manage */ \ + kMatterAccessPrivilegeManage, /* Cluster: Groups, Command: RemoveAllGroups, Privilege: manage */ \ + kMatterAccessPrivilegeManage, /* Cluster: Groups, Command: AddGroupIfIdentifying, Privilege: manage */ \ + kMatterAccessPrivilegeAdminister, /* Cluster: General Commissioning, Command: ArmFailSafe, Privilege: administer */ \ + kMatterAccessPrivilegeAdminister, /* Cluster: General Commissioning, Command: SetRegulatoryConfig, Privilege: administer */ \ + kMatterAccessPrivilegeAdminister, /* Cluster: General Commissioning, Command: CommissioningComplete, Privilege: administer */ \ + kMatterAccessPrivilegeAdminister, /* Cluster: Network Commissioning, Command: ScanNetworks, Privilege: administer */ \ + kMatterAccessPrivilegeAdminister, /* Cluster: Network Commissioning, Command: AddOrUpdateWiFiNetwork, Privilege: administer */ \ + kMatterAccessPrivilegeAdminister, /* Cluster: Network Commissioning, Command: AddOrUpdateThreadNetwork, Privilege: administer */ \ + kMatterAccessPrivilegeAdminister, /* Cluster: Network Commissioning, Command: RemoveNetwork, Privilege: administer */ \ + kMatterAccessPrivilegeAdminister, /* Cluster: Network Commissioning, Command: ConnectNetwork, Privilege: administer */ \ + kMatterAccessPrivilegeAdminister, /* Cluster: Network Commissioning, Command: ReorderNetwork, Privilege: administer */ \ + kMatterAccessPrivilegeManage, /* Cluster: General Diagnostics, Command: TestEventTrigger, Privilege: manage */ \ + kMatterAccessPrivilegeAdminister, /* Cluster: AdministratorCommissioning, Command: OpenCommissioningWindow, Privilege: administer */ \ + kMatterAccessPrivilegeAdminister, /* Cluster: AdministratorCommissioning, Command: OpenBasicCommissioningWindow, Privilege: administer */ \ + kMatterAccessPrivilegeAdminister, /* Cluster: AdministratorCommissioning, Command: RevokeCommissioning, Privilege: administer */ \ + kMatterAccessPrivilegeAdminister, /* Cluster: Operational Credentials, Command: AttestationRequest, Privilege: administer */ \ + kMatterAccessPrivilegeAdminister, /* Cluster: Operational Credentials, Command: CertificateChainRequest, Privilege: administer */ \ + kMatterAccessPrivilegeAdminister, /* Cluster: Operational Credentials, Command: CSRRequest, Privilege: administer */ \ + kMatterAccessPrivilegeAdminister, /* Cluster: Operational Credentials, Command: AddNOC, Privilege: administer */ \ + kMatterAccessPrivilegeAdminister, /* Cluster: Operational Credentials, Command: UpdateNOC, Privilege: administer */ \ + kMatterAccessPrivilegeAdminister, /* Cluster: Operational Credentials, Command: UpdateFabricLabel, Privilege: administer */ \ + kMatterAccessPrivilegeAdminister, /* Cluster: Operational Credentials, Command: RemoveFabric, Privilege: administer */ \ + kMatterAccessPrivilegeAdminister, /* Cluster: Operational Credentials, Command: AddTrustedRootCertificate, Privilege: administer */ \ + kMatterAccessPrivilegeAdminister, /* Cluster: Group Key Management, Command: KeySetWrite, Privilege: administer */ \ + kMatterAccessPrivilegeAdminister, /* Cluster: Group Key Management, Command: KeySetRead, Privilege: administer */ \ + kMatterAccessPrivilegeAdminister, /* Cluster: Group Key Management, Command: KeySetRemove, Privilege: administer */ \ + kMatterAccessPrivilegeAdminister, /* Cluster: Group Key Management, Command: KeySetReadAllIndices, Privilege: administer */ \ +} + +//////////////////////////////////////////////////////////////////////////////// + +// Parallel array data (*cluster*, event, privilege) for read event +#define GENERATED_ACCESS_READ_EVENT__CLUSTER { \ + 31, /* Cluster: Access Control, Event: AccessControlEntryChanged, Privilege: administer */ \ + 31, /* Cluster: Access Control, Event: AccessControlExtensionChanged, Privilege: administer */ \ +} + +// Parallel array data (cluster, *event*, privilege) for read event +#define GENERATED_ACCESS_READ_EVENT__EVENT { \ + 0, /* Cluster: Access Control, Event: AccessControlEntryChanged, Privilege: administer */ \ + 1, /* Cluster: Access Control, Event: AccessControlExtensionChanged, Privilege: administer */ \ +} + +// Parallel array data (cluster, event, *privilege*) for read event +#define GENERATED_ACCESS_READ_EVENT__PRIVILEGE { \ + kMatterAccessPrivilegeAdminister, /* Cluster: Access Control, Event: AccessControlEntryChanged, Privilege: administer */ \ + kMatterAccessPrivilegeAdminister, /* Cluster: Access Control, Event: AccessControlExtensionChanged, Privilege: administer */ \ +} + +//////////////////////////////////////////////////////////////////////////////// + +// clang-format on diff --git a/zzz_generated/contact-sensor-app/zap-generated/af-gen-event.h b/zzz_generated/contact-sensor-app/zap-generated/af-gen-event.h new file mode 100755 index 00000000000000..e69de29bb2d1d6 diff --git a/zzz_generated/contact-sensor-app/zap-generated/callback-stub.cpp b/zzz_generated/contact-sensor-app/zap-generated/callback-stub.cpp new file mode 100644 index 00000000000000..c61d4b45f26c1b --- /dev/null +++ b/zzz_generated/contact-sensor-app/zap-generated/callback-stub.cpp @@ -0,0 +1,319 @@ +/* + * + * 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 + +#include +#include +#include +#include + +using namespace chip; + +// Cluster Init Functions +void emberAfClusterInitCallback(EndpointId endpoint, ClusterId clusterId) +{ + switch (clusterId) + { + case ZCL_ACCESS_CONTROL_CLUSTER_ID: + emberAfAccessControlClusterInitCallback(endpoint); + break; + case ZCL_ADMINISTRATOR_COMMISSIONING_CLUSTER_ID: + emberAfAdministratorCommissioningClusterInitCallback(endpoint); + break; + case ZCL_BASIC_CLUSTER_ID: + emberAfBasicClusterInitCallback(endpoint); + break; + case ZCL_BOOLEAN_STATE_CLUSTER_ID: + emberAfBooleanStateClusterInitCallback(endpoint); + break; + case ZCL_DESCRIPTOR_CLUSTER_ID: + emberAfDescriptorClusterInitCallback(endpoint); + break; + case ZCL_DIAGNOSTIC_LOGS_CLUSTER_ID: + emberAfDiagnosticLogsClusterInitCallback(endpoint); + break; + case ZCL_ETHERNET_NETWORK_DIAGNOSTICS_CLUSTER_ID: + emberAfEthernetNetworkDiagnosticsClusterInitCallback(endpoint); + break; + case ZCL_FIXED_LABEL_CLUSTER_ID: + emberAfFixedLabelClusterInitCallback(endpoint); + break; + case ZCL_GENERAL_COMMISSIONING_CLUSTER_ID: + emberAfGeneralCommissioningClusterInitCallback(endpoint); + break; + case ZCL_GENERAL_DIAGNOSTICS_CLUSTER_ID: + emberAfGeneralDiagnosticsClusterInitCallback(endpoint); + break; + case ZCL_GROUP_KEY_MANAGEMENT_CLUSTER_ID: + emberAfGroupKeyManagementClusterInitCallback(endpoint); + break; + case ZCL_GROUPS_CLUSTER_ID: + emberAfGroupsClusterInitCallback(endpoint); + break; + case ZCL_IDENTIFY_CLUSTER_ID: + emberAfIdentifyClusterInitCallback(endpoint); + break; + case ZCL_LOCALIZATION_CONFIGURATION_CLUSTER_ID: + emberAfLocalizationConfigurationClusterInitCallback(endpoint); + break; + case ZCL_NETWORK_COMMISSIONING_CLUSTER_ID: + emberAfNetworkCommissioningClusterInitCallback(endpoint); + break; + case ZCL_OTA_PROVIDER_CLUSTER_ID: + emberAfOtaSoftwareUpdateProviderClusterInitCallback(endpoint); + break; + case ZCL_OTA_REQUESTOR_CLUSTER_ID: + emberAfOtaSoftwareUpdateRequestorClusterInitCallback(endpoint); + break; + case ZCL_OCCUPANCY_SENSING_CLUSTER_ID: + emberAfOccupancySensingClusterInitCallback(endpoint); + break; + case ZCL_OPERATIONAL_CREDENTIALS_CLUSTER_ID: + emberAfOperationalCredentialsClusterInitCallback(endpoint); + break; + case ZCL_SOFTWARE_DIAGNOSTICS_CLUSTER_ID: + emberAfSoftwareDiagnosticsClusterInitCallback(endpoint); + break; + case ZCL_THREAD_NETWORK_DIAGNOSTICS_CLUSTER_ID: + emberAfThreadNetworkDiagnosticsClusterInitCallback(endpoint); + break; + case ZCL_TIME_FORMAT_LOCALIZATION_CLUSTER_ID: + emberAfTimeFormatLocalizationClusterInitCallback(endpoint); + break; + case ZCL_USER_LABEL_CLUSTER_ID: + emberAfUserLabelClusterInitCallback(endpoint); + break; + case ZCL_WIFI_NETWORK_DIAGNOSTICS_CLUSTER_ID: + emberAfWiFiNetworkDiagnosticsClusterInitCallback(endpoint); + break; + default: + // Unrecognized cluster ID + break; + } +} + +void __attribute__((weak)) emberAfAccessControlClusterInitCallback(EndpointId endpoint) +{ + // To prevent warning + (void) endpoint; +} +void __attribute__((weak)) emberAfAdministratorCommissioningClusterInitCallback(EndpointId endpoint) +{ + // To prevent warning + (void) endpoint; +} +void __attribute__((weak)) emberAfBasicClusterInitCallback(EndpointId endpoint) +{ + // To prevent warning + (void) endpoint; +} +void __attribute__((weak)) emberAfBooleanStateClusterInitCallback(EndpointId endpoint) +{ + // To prevent warning + (void) endpoint; +} +void __attribute__((weak)) emberAfDescriptorClusterInitCallback(EndpointId endpoint) +{ + // To prevent warning + (void) endpoint; +} +void __attribute__((weak)) emberAfDiagnosticLogsClusterInitCallback(EndpointId endpoint) +{ + // To prevent warning + (void) endpoint; +} +void __attribute__((weak)) emberAfEthernetNetworkDiagnosticsClusterInitCallback(EndpointId endpoint) +{ + // To prevent warning + (void) endpoint; +} +void __attribute__((weak)) emberAfFixedLabelClusterInitCallback(EndpointId endpoint) +{ + // To prevent warning + (void) endpoint; +} +void __attribute__((weak)) emberAfGeneralCommissioningClusterInitCallback(EndpointId endpoint) +{ + // To prevent warning + (void) endpoint; +} +void __attribute__((weak)) emberAfGeneralDiagnosticsClusterInitCallback(EndpointId endpoint) +{ + // To prevent warning + (void) endpoint; +} +void __attribute__((weak)) emberAfGroupKeyManagementClusterInitCallback(EndpointId endpoint) +{ + // To prevent warning + (void) endpoint; +} +void __attribute__((weak)) emberAfGroupsClusterInitCallback(EndpointId endpoint) +{ + // To prevent warning + (void) endpoint; +} +void __attribute__((weak)) emberAfIdentifyClusterInitCallback(EndpointId endpoint) +{ + // To prevent warning + (void) endpoint; +} +void __attribute__((weak)) emberAfLocalizationConfigurationClusterInitCallback(EndpointId endpoint) +{ + // To prevent warning + (void) endpoint; +} +void __attribute__((weak)) emberAfNetworkCommissioningClusterInitCallback(EndpointId endpoint) +{ + // To prevent warning + (void) endpoint; +} +void __attribute__((weak)) emberAfOtaSoftwareUpdateProviderClusterInitCallback(EndpointId endpoint) +{ + // To prevent warning + (void) endpoint; +} +void __attribute__((weak)) emberAfOtaSoftwareUpdateRequestorClusterInitCallback(EndpointId endpoint) +{ + // To prevent warning + (void) endpoint; +} +void __attribute__((weak)) emberAfOccupancySensingClusterInitCallback(EndpointId endpoint) +{ + // To prevent warning + (void) endpoint; +} +void __attribute__((weak)) emberAfOperationalCredentialsClusterInitCallback(EndpointId endpoint) +{ + // To prevent warning + (void) endpoint; +} +void __attribute__((weak)) emberAfSoftwareDiagnosticsClusterInitCallback(EndpointId endpoint) +{ + // To prevent warning + (void) endpoint; +} +void __attribute__((weak)) emberAfThreadNetworkDiagnosticsClusterInitCallback(EndpointId endpoint) +{ + // To prevent warning + (void) endpoint; +} +void __attribute__((weak)) emberAfTimeFormatLocalizationClusterInitCallback(EndpointId endpoint) +{ + // To prevent warning + (void) endpoint; +} +void __attribute__((weak)) emberAfUserLabelClusterInitCallback(EndpointId endpoint) +{ + // To prevent warning + (void) endpoint; +} +void __attribute__((weak)) emberAfWiFiNetworkDiagnosticsClusterInitCallback(EndpointId endpoint) +{ + // To prevent warning + (void) endpoint; +} + +// +// Non-Cluster Related Callbacks +// + +void __attribute__((weak)) emberAfAddToCurrentAppTasksCallback(EmberAfApplicationTask tasks) {} + +void __attribute__((weak)) emberAfRemoveFromCurrentAppTasksCallback(EmberAfApplicationTask tasks) {} + +EmberAfAttributeWritePermission __attribute__((weak)) +emberAfAllowNetworkWriteAttributeCallback(EndpointId endpoint, ClusterId clusterId, AttributeId attributeId, uint8_t * value, + uint8_t type) +{ + return EMBER_ZCL_ATTRIBUTE_WRITE_PERMISSION_ALLOW_WRITE_NORMAL; // Default +} + +bool __attribute__((weak)) emberAfAttributeReadAccessCallback(EndpointId endpoint, ClusterId clusterId, AttributeId attributeId) +{ + return true; +} + +bool __attribute__((weak)) emberAfAttributeWriteAccessCallback(EndpointId endpoint, ClusterId clusterId, AttributeId attributeId) +{ + return true; +} + +bool __attribute__((weak)) emberAfDefaultResponseCallback(ClusterId clusterId, CommandId commandId, EmberAfStatus status) +{ + return false; +} + +bool __attribute__((weak)) emberAfPreMessageSendCallback(EmberAfMessageStruct * messageStruct, EmberStatus * status) +{ + return false; +} + +bool __attribute__((weak)) emberAfMessageSentCallback(const MessageSendDestination & destination, EmberApsFrame * apsFrame, + uint16_t msgLen, uint8_t * message, EmberStatus status) +{ + return false; +} + +EmberAfStatus __attribute__((weak)) +emberAfExternalAttributeReadCallback(EndpointId endpoint, ClusterId clusterId, const EmberAfAttributeMetadata * attributeMetadata, + uint8_t * buffer, uint16_t maxReadLength) +{ + return EMBER_ZCL_STATUS_FAILURE; +} + +EmberAfStatus __attribute__((weak)) +emberAfExternalAttributeWriteCallback(EndpointId endpoint, ClusterId clusterId, const EmberAfAttributeMetadata * attributeMetadata, + uint8_t * buffer) +{ + return EMBER_ZCL_STATUS_FAILURE; +} + +uint32_t __attribute__((weak)) emberAfGetCurrentTimeCallback() +{ + return 0; +} + +bool __attribute__((weak)) +emberAfGetEndpointInfoCallback(EndpointId endpoint, uint8_t * returnNetworkIndex, EmberAfEndpointInfoStruct * returnEndpointInfo) +{ + return false; +} + +void __attribute__((weak)) emberAfRegistrationAbortCallback() {} + +EmberStatus __attribute__((weak)) +emberAfInterpanSendMessageCallback(EmberAfInterpanHeader * header, uint16_t messageLength, uint8_t * message) +{ + return EMBER_LIBRARY_NOT_PRESENT; +} + +bool __attribute__((weak)) emberAfStartMoveCallback() +{ + return false; +} + +chip::Protocols::InteractionModel::Status __attribute__((weak)) +MatterPreAttributeChangeCallback(const chip::app::ConcreteAttributePath & attributePath, uint8_t type, uint16_t size, + uint8_t * value) +{ + return chip::Protocols::InteractionModel::Status::Success; +} + +void __attribute__((weak)) MatterPostAttributeChangeCallback(const chip::app::ConcreteAttributePath & attributePath, uint8_t type, + uint16_t size, uint8_t * value) +{} diff --git a/zzz_generated/contact-sensor-app/zap-generated/endpoint_config.h b/zzz_generated/contact-sensor-app/zap-generated/endpoint_config.h new file mode 100644 index 00000000000000..a33b1516cd7ab3 --- /dev/null +++ b/zzz_generated/contact-sensor-app/zap-generated/endpoint_config.h @@ -0,0 +1,964 @@ +/* + * + * 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 + +// Prevent multiple inclusion +#pragma once + +#include + +// Default values for the attributes longer than a pointer, +// in a form of a binary blob +// Separate block is generated for big-endian and little-endian cases. +#if BIGENDIAN_CPU +#define GENERATED_DEFAULTS \ + { \ + \ + /* Endpoint: 0, Cluster: Localization Configuration (server), big-endian */ \ + \ + /* 0 - ActiveLocale, */ \ + 5, 'e', 'n', '-', 'U', 'S', \ + \ + /* Endpoint: 0, Cluster: General Commissioning (server), big-endian */ \ + \ + /* 6 - Breadcrumb, */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + } + +#else // !BIGENDIAN_CPU +#define GENERATED_DEFAULTS \ + { \ + \ + /* Endpoint: 0, Cluster: Localization Configuration (server), little-endian */ \ + \ + /* 0 - ActiveLocale, */ \ + 5, 'e', 'n', '-', 'U', 'S', \ + \ + /* Endpoint: 0, Cluster: General Commissioning (server), little-endian */ \ + \ + /* 6 - Breadcrumb, */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + } + +#endif // BIGENDIAN_CPU + +#define GENERATED_DEFAULTS_COUNT (2) + +#define ZAP_TYPE(type) ZCL_##type##_ATTRIBUTE_TYPE +#define ZAP_LONG_DEFAULTS_INDEX(index) \ + { \ + &generatedDefaults[index] \ + } +#define ZAP_MIN_MAX_DEFAULTS_INDEX(index) \ + { \ + &minMaxDefaults[index] \ + } +#define ZAP_EMPTY_DEFAULT() \ + { \ + (uint32_t) 0 \ + } +#define ZAP_SIMPLE_DEFAULT(x) \ + { \ + (uint32_t) x \ + } + +// This is an array of EmberAfAttributeMinMaxValue structures. +#define GENERATED_MIN_MAX_DEFAULT_COUNT 1 +#define GENERATED_MIN_MAX_DEFAULTS \ + { \ + \ + /* Endpoint: 0, Cluster: Time Format Localization (server) */ \ + { \ + (uint16_t) 0x0, (uint16_t) 0x0, (uint16_t) 0x1 \ + } /* HourFormat */ \ + } + +#define ZAP_ATTRIBUTE_MASK(mask) ATTRIBUTE_MASK_##mask +// This is an array of EmberAfAttributeMetadata structures. +#define GENERATED_ATTRIBUTE_COUNT 223 +#define GENERATED_ATTRIBUTES \ + { \ + \ + /* Endpoint: 0, Cluster: Groups (server) */ \ + { 0x00000000, ZAP_TYPE(BITMAP8), 1, 0, ZAP_EMPTY_DEFAULT() }, /* name support */ \ + { 0x0000FFFC, ZAP_TYPE(BITMAP32), 4, 0, ZAP_SIMPLE_DEFAULT(0) }, /* FeatureMap */ \ + { 0x0000FFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(4) }, /* ClusterRevision */ \ + \ + /* Endpoint: 0, Cluster: Descriptor (server) */ \ + { 0x00000000, ZAP_TYPE(ARRAY), 0, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* DeviceTypeList */ \ + { 0x00000001, ZAP_TYPE(ARRAY), 0, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* ServerList */ \ + { 0x00000002, ZAP_TYPE(ARRAY), 0, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* ClientList */ \ + { 0x00000003, ZAP_TYPE(ARRAY), 0, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* PartsList */ \ + { 0x0000FFFC, ZAP_TYPE(BITMAP32), 4, 0, ZAP_SIMPLE_DEFAULT(0) }, /* FeatureMap */ \ + { 0x0000FFFD, ZAP_TYPE(INT16U), 2, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* ClusterRevision */ \ + \ + /* Endpoint: 0, Cluster: Access Control (server) */ \ + { 0x00000000, ZAP_TYPE(ARRAY), 0, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(WRITABLE), \ + ZAP_EMPTY_DEFAULT() }, /* ACL */ \ + { 0x00000001, ZAP_TYPE(ARRAY), 0, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(WRITABLE), \ + ZAP_EMPTY_DEFAULT() }, /* Extension */ \ + { 0x00000002, ZAP_TYPE(INT16U), 2, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), \ + ZAP_EMPTY_DEFAULT() }, /* SubjectsPerAccessControlEntry */ \ + { 0x00000003, ZAP_TYPE(INT16U), 2, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), \ + ZAP_EMPTY_DEFAULT() }, /* TargetsPerAccessControlEntry */ \ + { 0x00000004, ZAP_TYPE(INT16U), 2, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), \ + ZAP_EMPTY_DEFAULT() }, /* AccessControlEntriesPerFabric */ \ + { 0x0000FFFC, ZAP_TYPE(BITMAP32), 4, 0, ZAP_SIMPLE_DEFAULT(0) }, /* FeatureMap */ \ + { 0x0000FFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(1) }, /* ClusterRevision */ \ + \ + /* Endpoint: 0, Cluster: Basic (server) */ \ + { 0x00000000, ZAP_TYPE(INT16U), 2, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(SINGLETON), \ + ZAP_EMPTY_DEFAULT() }, /* DataModelRevision */ \ + { 0x00000001, ZAP_TYPE(CHAR_STRING), 33, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(SINGLETON), \ + ZAP_EMPTY_DEFAULT() }, /* VendorName */ \ + { 0x00000002, ZAP_TYPE(VENDOR_ID), 2, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(SINGLETON), \ + ZAP_EMPTY_DEFAULT() }, /* VendorID */ \ + { 0x00000003, ZAP_TYPE(CHAR_STRING), 33, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(SINGLETON), \ + ZAP_EMPTY_DEFAULT() }, /* ProductName */ \ + { 0x00000004, ZAP_TYPE(INT16U), 2, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(SINGLETON), \ + ZAP_EMPTY_DEFAULT() }, /* ProductID */ \ + { 0x00000005, ZAP_TYPE(CHAR_STRING), 33, \ + ZAP_ATTRIBUTE_MASK(TOKENIZE) | ZAP_ATTRIBUTE_MASK(SINGLETON) | ZAP_ATTRIBUTE_MASK(WRITABLE), \ + ZAP_EMPTY_DEFAULT() }, /* NodeLabel */ \ + { 0x00000006, ZAP_TYPE(CHAR_STRING), 3, \ + ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(SINGLETON) | ZAP_ATTRIBUTE_MASK(WRITABLE), \ + ZAP_EMPTY_DEFAULT() }, /* Location */ \ + { 0x00000007, ZAP_TYPE(INT16U), 2, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(SINGLETON), \ + ZAP_EMPTY_DEFAULT() }, /* HardwareVersion */ \ + { 0x00000008, ZAP_TYPE(CHAR_STRING), 65, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(SINGLETON), \ + ZAP_EMPTY_DEFAULT() }, /* HardwareVersionString */ \ + { 0x00000009, ZAP_TYPE(INT32U), 4, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(SINGLETON), \ + ZAP_EMPTY_DEFAULT() }, /* SoftwareVersion */ \ + { 0x0000000A, ZAP_TYPE(CHAR_STRING), 65, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(SINGLETON), \ + ZAP_EMPTY_DEFAULT() }, /* SoftwareVersionString */ \ + { 0x0000000B, ZAP_TYPE(CHAR_STRING), 17, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(SINGLETON), \ + ZAP_EMPTY_DEFAULT() }, /* ManufacturingDate */ \ + { 0x0000000C, ZAP_TYPE(CHAR_STRING), 33, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(SINGLETON), \ + ZAP_EMPTY_DEFAULT() }, /* PartNumber */ \ + { 0x0000000D, ZAP_TYPE(LONG_CHAR_STRING), 258, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(SINGLETON), \ + ZAP_EMPTY_DEFAULT() }, /* ProductURL */ \ + { 0x0000000E, ZAP_TYPE(CHAR_STRING), 65, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(SINGLETON), \ + ZAP_EMPTY_DEFAULT() }, /* ProductLabel */ \ + { 0x0000000F, ZAP_TYPE(CHAR_STRING), 33, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(SINGLETON), \ + ZAP_EMPTY_DEFAULT() }, /* SerialNumber */ \ + { 0x00000010, ZAP_TYPE(BOOLEAN), 1, \ + ZAP_ATTRIBUTE_MASK(TOKENIZE) | ZAP_ATTRIBUTE_MASK(SINGLETON) | ZAP_ATTRIBUTE_MASK(WRITABLE), \ + ZAP_SIMPLE_DEFAULT(0) }, /* LocalConfigDisabled */ \ + { 0x00000011, ZAP_TYPE(BOOLEAN), 1, ZAP_ATTRIBUTE_MASK(SINGLETON), ZAP_SIMPLE_DEFAULT(1) }, /* Reachable */ \ + { 0x00000012, ZAP_TYPE(CHAR_STRING), 33, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(SINGLETON), \ + ZAP_EMPTY_DEFAULT() }, /* UniqueID */ \ + { 0x00000013, ZAP_TYPE(STRUCT), 0, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* CapabilityMinima */ \ + { 0x0000FFFC, ZAP_TYPE(BITMAP32), 4, 0, ZAP_SIMPLE_DEFAULT(0) }, /* FeatureMap */ \ + { 0x0000FFFD, ZAP_TYPE(INT16U), 2, ZAP_ATTRIBUTE_MASK(SINGLETON), ZAP_SIMPLE_DEFAULT(1) }, /* ClusterRevision */ \ + \ + /* Endpoint: 0, Cluster: OTA Software Update Requestor (server) */ \ + { 0x00000000, ZAP_TYPE(ARRAY), 0, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(WRITABLE), \ + ZAP_EMPTY_DEFAULT() }, /* DefaultOtaProviders */ \ + { 0x00000001, ZAP_TYPE(BOOLEAN), 1, 0, ZAP_SIMPLE_DEFAULT(1) }, /* UpdatePossible */ \ + { 0x00000002, ZAP_TYPE(ENUM8), 1, 0, ZAP_SIMPLE_DEFAULT(0) }, /* UpdateState */ \ + { 0x00000003, ZAP_TYPE(INT8U), 1, ZAP_ATTRIBUTE_MASK(NULLABLE), ZAP_SIMPLE_DEFAULT(0) }, /* UpdateStateProgress */ \ + { 0x0000FFFC, ZAP_TYPE(BITMAP32), 4, 0, ZAP_SIMPLE_DEFAULT(0) }, /* FeatureMap */ \ + { 0x0000FFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(1) }, /* ClusterRevision */ \ + \ + /* Endpoint: 0, Cluster: Localization Configuration (server) */ \ + { 0x00000000, ZAP_TYPE(CHAR_STRING), 36, ZAP_ATTRIBUTE_MASK(TOKENIZE) | ZAP_ATTRIBUTE_MASK(WRITABLE), \ + ZAP_LONG_DEFAULTS_INDEX(0) }, /* ActiveLocale */ \ + { 0x00000001, ZAP_TYPE(ARRAY), 0, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* SupportedLocales */ \ + { 0x0000FFFC, ZAP_TYPE(BITMAP32), 4, 0, ZAP_SIMPLE_DEFAULT(0) }, /* FeatureMap */ \ + { 0x0000FFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(1) }, /* ClusterRevision */ \ + \ + /* Endpoint: 0, Cluster: Time Format Localization (server) */ \ + { 0x00000000, ZAP_TYPE(ENUM8), 1, \ + ZAP_ATTRIBUTE_MASK(MIN_MAX) | ZAP_ATTRIBUTE_MASK(TOKENIZE) | ZAP_ATTRIBUTE_MASK(WRITABLE), \ + ZAP_MIN_MAX_DEFAULTS_INDEX(0) }, /* HourFormat */ \ + { 0x00000001, ZAP_TYPE(ENUM8), 1, ZAP_ATTRIBUTE_MASK(TOKENIZE) | ZAP_ATTRIBUTE_MASK(WRITABLE), \ + ZAP_SIMPLE_DEFAULT(0) }, /* ActiveCalendarType */ \ + { 0x00000002, ZAP_TYPE(ARRAY), 0, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), \ + ZAP_EMPTY_DEFAULT() }, /* SupportedCalendarTypes */ \ + { 0x0000FFFC, ZAP_TYPE(BITMAP32), 4, 0, ZAP_SIMPLE_DEFAULT(0) }, /* FeatureMap */ \ + { 0x0000FFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(1) }, /* ClusterRevision */ \ + \ + /* Endpoint: 0, Cluster: General Commissioning (server) */ \ + { 0x00000000, ZAP_TYPE(INT64U), 8, ZAP_ATTRIBUTE_MASK(WRITABLE), ZAP_LONG_DEFAULTS_INDEX(6) }, /* Breadcrumb */ \ + { 0x00000001, ZAP_TYPE(STRUCT), 0, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), \ + ZAP_EMPTY_DEFAULT() }, /* BasicCommissioningInfo */ \ + { 0x00000002, ZAP_TYPE(ENUM8), 1, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* RegulatoryConfig */ \ + { 0x00000003, ZAP_TYPE(ENUM8), 1, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), \ + ZAP_EMPTY_DEFAULT() }, /* LocationCapability */ \ + { 0x00000004, ZAP_TYPE(BOOLEAN), 1, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), \ + ZAP_EMPTY_DEFAULT() }, /* SupportsConcurrentConnection */ \ + { 0x0000FFFC, ZAP_TYPE(BITMAP32), 4, 0, ZAP_SIMPLE_DEFAULT(6) }, /* FeatureMap */ \ + { 0x0000FFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(1) }, /* ClusterRevision */ \ + \ + /* Endpoint: 0, Cluster: Network Commissioning (server) */ \ + { 0x00000000, ZAP_TYPE(INT8U), 1, 0, ZAP_EMPTY_DEFAULT() }, /* MaxNetworks */ \ + { 0x00000001, ZAP_TYPE(ARRAY), 0, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* Networks */ \ + { 0x00000002, ZAP_TYPE(INT8U), 1, 0, ZAP_EMPTY_DEFAULT() }, /* ScanMaxTimeSeconds */ \ + { 0x00000003, ZAP_TYPE(INT8U), 1, 0, ZAP_EMPTY_DEFAULT() }, /* ConnectMaxTimeSeconds */ \ + { 0x00000004, ZAP_TYPE(BOOLEAN), 1, ZAP_ATTRIBUTE_MASK(WRITABLE), ZAP_EMPTY_DEFAULT() }, /* InterfaceEnabled */ \ + { 0x00000005, ZAP_TYPE(ENUM8), 1, ZAP_ATTRIBUTE_MASK(NULLABLE), ZAP_EMPTY_DEFAULT() }, /* LastNetworkingStatus */ \ + { 0x00000006, ZAP_TYPE(OCTET_STRING), 33, ZAP_ATTRIBUTE_MASK(NULLABLE), ZAP_EMPTY_DEFAULT() }, /* LastNetworkID */ \ + { 0x00000007, ZAP_TYPE(INT32S), 4, ZAP_ATTRIBUTE_MASK(NULLABLE), ZAP_EMPTY_DEFAULT() }, /* LastConnectErrorValue */ \ + { 0x0000FFFC, ZAP_TYPE(BITMAP32), 4, 0, ZAP_SIMPLE_DEFAULT(2) }, /* FeatureMap */ \ + { 0x0000FFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(1) }, /* ClusterRevision */ \ + \ + /* Endpoint: 0, Cluster: Diagnostic Logs (server) */ \ + { 0x0000FFFC, ZAP_TYPE(BITMAP32), 4, 0, ZAP_SIMPLE_DEFAULT(0) }, /* FeatureMap */ \ + { 0x0000FFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(1) }, /* ClusterRevision */ \ + \ + /* Endpoint: 0, Cluster: General Diagnostics (server) */ \ + { 0x00000000, ZAP_TYPE(ARRAY), 0, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* NetworkInterfaces */ \ + { 0x00000001, ZAP_TYPE(INT16U), 2, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* RebootCount */ \ + { 0x00000002, ZAP_TYPE(INT64U), 8, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* UpTime */ \ + { 0x00000003, ZAP_TYPE(INT32U), 4, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), \ + ZAP_EMPTY_DEFAULT() }, /* TotalOperationalHours */ \ + { 0x00000004, ZAP_TYPE(ENUM8), 1, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* BootReasons */ \ + { 0x00000005, ZAP_TYPE(ARRAY), 0, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), \ + ZAP_EMPTY_DEFAULT() }, /* ActiveHardwareFaults */ \ + { 0x00000006, ZAP_TYPE(ARRAY), 0, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* ActiveRadioFaults */ \ + { 0x00000007, ZAP_TYPE(ARRAY), 0, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), \ + ZAP_EMPTY_DEFAULT() }, /* ActiveNetworkFaults */ \ + { 0x00000008, ZAP_TYPE(BOOLEAN), 1, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), \ + ZAP_EMPTY_DEFAULT() }, /* TestEventTriggersEnabled */ \ + { 0x0000FFFC, ZAP_TYPE(BITMAP32), 4, 0, ZAP_SIMPLE_DEFAULT(0) }, /* FeatureMap */ \ + { 0x0000FFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(1) }, /* ClusterRevision */ \ + \ + /* Endpoint: 0, Cluster: Software Diagnostics (server) */ \ + { 0x00000000, ZAP_TYPE(ARRAY), 0, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* ThreadMetrics */ \ + { 0x00000001, ZAP_TYPE(INT64U), 8, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* CurrentHeapFree */ \ + { 0x00000002, ZAP_TYPE(INT64U), 8, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* CurrentHeapUsed */ \ + { 0x00000003, ZAP_TYPE(INT64U), 8, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), \ + ZAP_EMPTY_DEFAULT() }, /* CurrentHeapHighWatermark */ \ + { 0x0000FFFC, ZAP_TYPE(BITMAP32), 4, 0, ZAP_SIMPLE_DEFAULT(1) }, /* FeatureMap */ \ + { 0x0000FFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(1) }, /* ClusterRevision */ \ + \ + /* Endpoint: 0, Cluster: Thread Network Diagnostics (server) */ \ + { 0x00000000, ZAP_TYPE(INT16U), 2, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(NULLABLE), \ + ZAP_EMPTY_DEFAULT() }, /* channel */ \ + { 0x00000001, ZAP_TYPE(ENUM8), 1, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(NULLABLE), \ + ZAP_EMPTY_DEFAULT() }, /* RoutingRole */ \ + { 0x00000002, ZAP_TYPE(CHAR_STRING), 17, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(NULLABLE), \ + ZAP_EMPTY_DEFAULT() }, /* NetworkName */ \ + { 0x00000003, ZAP_TYPE(INT16U), 2, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(NULLABLE), \ + ZAP_EMPTY_DEFAULT() }, /* PanId */ \ + { 0x00000004, ZAP_TYPE(INT64U), 8, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(NULLABLE), \ + ZAP_EMPTY_DEFAULT() }, /* ExtendedPanId */ \ + { 0x00000005, ZAP_TYPE(OCTET_STRING), 18, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(NULLABLE), \ + ZAP_EMPTY_DEFAULT() }, /* MeshLocalPrefix */ \ + { 0x00000006, ZAP_TYPE(INT64U), 8, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* OverrunCount */ \ + { 0x00000007, ZAP_TYPE(ARRAY), 0, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* NeighborTableList */ \ + { 0x00000008, ZAP_TYPE(ARRAY), 0, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* RouteTableList */ \ + { 0x00000009, ZAP_TYPE(INT32U), 4, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(NULLABLE), \ + ZAP_EMPTY_DEFAULT() }, /* PartitionId */ \ + { 0x0000000A, ZAP_TYPE(INT8U), 1, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(NULLABLE), \ + ZAP_EMPTY_DEFAULT() }, /* weighting */ \ + { 0x0000000B, ZAP_TYPE(INT8U), 1, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(NULLABLE), \ + ZAP_EMPTY_DEFAULT() }, /* DataVersion */ \ + { 0x0000000C, ZAP_TYPE(INT8U), 1, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(NULLABLE), \ + ZAP_EMPTY_DEFAULT() }, /* StableDataVersion */ \ + { 0x0000000D, ZAP_TYPE(INT8U), 1, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(NULLABLE), \ + ZAP_EMPTY_DEFAULT() }, /* LeaderRouterId */ \ + { 0x0000000E, ZAP_TYPE(INT16U), 2, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), \ + ZAP_EMPTY_DEFAULT() }, /* DetachedRoleCount */ \ + { 0x0000000F, ZAP_TYPE(INT16U), 2, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* ChildRoleCount */ \ + { 0x00000010, ZAP_TYPE(INT16U), 2, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* RouterRoleCount */ \ + { 0x00000011, ZAP_TYPE(INT16U), 2, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* LeaderRoleCount */ \ + { 0x00000012, ZAP_TYPE(INT16U), 2, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), \ + ZAP_EMPTY_DEFAULT() }, /* AttachAttemptCount */ \ + { 0x00000013, ZAP_TYPE(INT16U), 2, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), \ + ZAP_EMPTY_DEFAULT() }, /* PartitionIdChangeCount */ \ + { 0x00000014, ZAP_TYPE(INT16U), 2, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), \ + ZAP_EMPTY_DEFAULT() }, /* BetterPartitionAttachAttemptCount */ \ + { 0x00000015, ZAP_TYPE(INT16U), 2, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), \ + ZAP_EMPTY_DEFAULT() }, /* ParentChangeCount */ \ + { 0x00000016, ZAP_TYPE(INT32U), 4, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* TxTotalCount */ \ + { 0x00000017, ZAP_TYPE(INT32U), 4, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* TxUnicastCount */ \ + { 0x00000018, ZAP_TYPE(INT32U), 4, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* TxBroadcastCount */ \ + { 0x00000019, ZAP_TYPE(INT32U), 4, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), \ + ZAP_EMPTY_DEFAULT() }, /* TxAckRequestedCount */ \ + { 0x0000001A, ZAP_TYPE(INT32U), 4, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* TxAckedCount */ \ + { 0x0000001B, ZAP_TYPE(INT32U), 4, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), \ + ZAP_EMPTY_DEFAULT() }, /* TxNoAckRequestedCount */ \ + { 0x0000001C, ZAP_TYPE(INT32U), 4, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* TxDataCount */ \ + { 0x0000001D, ZAP_TYPE(INT32U), 4, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* TxDataPollCount */ \ + { 0x0000001E, ZAP_TYPE(INT32U), 4, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* TxBeaconCount */ \ + { 0x0000001F, ZAP_TYPE(INT32U), 4, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), \ + ZAP_EMPTY_DEFAULT() }, /* TxBeaconRequestCount */ \ + { 0x00000020, ZAP_TYPE(INT32U), 4, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* TxOtherCount */ \ + { 0x00000021, ZAP_TYPE(INT32U), 4, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* TxRetryCount */ \ + { 0x00000022, ZAP_TYPE(INT32U), 4, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), \ + ZAP_EMPTY_DEFAULT() }, /* TxDirectMaxRetryExpiryCount */ \ + { 0x00000023, ZAP_TYPE(INT32U), 4, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), \ + ZAP_EMPTY_DEFAULT() }, /* TxIndirectMaxRetryExpiryCount */ \ + { 0x00000024, ZAP_TYPE(INT32U), 4, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* TxErrCcaCount */ \ + { 0x00000025, ZAP_TYPE(INT32U), 4, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* TxErrAbortCount */ \ + { 0x00000026, ZAP_TYPE(INT32U), 4, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), \ + ZAP_EMPTY_DEFAULT() }, /* TxErrBusyChannelCount */ \ + { 0x00000027, ZAP_TYPE(INT32U), 4, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* RxTotalCount */ \ + { 0x00000028, ZAP_TYPE(INT32U), 4, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* RxUnicastCount */ \ + { 0x00000029, ZAP_TYPE(INT32U), 4, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* RxBroadcastCount */ \ + { 0x0000002A, ZAP_TYPE(INT32U), 4, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* RxDataCount */ \ + { 0x0000002B, ZAP_TYPE(INT32U), 4, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* RxDataPollCount */ \ + { 0x0000002C, ZAP_TYPE(INT32U), 4, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* RxBeaconCount */ \ + { 0x0000002D, ZAP_TYPE(INT32U), 4, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), \ + ZAP_EMPTY_DEFAULT() }, /* RxBeaconRequestCount */ \ + { 0x0000002E, ZAP_TYPE(INT32U), 4, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* RxOtherCount */ \ + { 0x0000002F, ZAP_TYPE(INT32U), 4, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), \ + ZAP_EMPTY_DEFAULT() }, /* RxAddressFilteredCount */ \ + { 0x00000030, ZAP_TYPE(INT32U), 4, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), \ + ZAP_EMPTY_DEFAULT() }, /* RxDestAddrFilteredCount */ \ + { 0x00000031, ZAP_TYPE(INT32U), 4, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), \ + ZAP_EMPTY_DEFAULT() }, /* RxDuplicatedCount */ \ + { 0x00000032, ZAP_TYPE(INT32U), 4, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), \ + ZAP_EMPTY_DEFAULT() }, /* RxErrNoFrameCount */ \ + { 0x00000033, ZAP_TYPE(INT32U), 4, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), \ + ZAP_EMPTY_DEFAULT() }, /* RxErrUnknownNeighborCount */ \ + { 0x00000034, ZAP_TYPE(INT32U), 4, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), \ + ZAP_EMPTY_DEFAULT() }, /* RxErrInvalidSrcAddrCount */ \ + { 0x00000035, ZAP_TYPE(INT32U), 4, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* RxErrSecCount */ \ + { 0x00000036, ZAP_TYPE(INT32U), 4, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* RxErrFcsCount */ \ + { 0x00000037, ZAP_TYPE(INT32U), 4, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* RxErrOtherCount */ \ + { 0x00000038, ZAP_TYPE(INT64U), 8, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(NULLABLE), \ + ZAP_EMPTY_DEFAULT() }, /* ActiveTimestamp */ \ + { 0x00000039, ZAP_TYPE(INT64U), 8, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(NULLABLE), \ + ZAP_EMPTY_DEFAULT() }, /* PendingTimestamp */ \ + { 0x0000003A, ZAP_TYPE(INT32U), 4, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(NULLABLE), \ + ZAP_EMPTY_DEFAULT() }, /* Delay */ \ + { 0x0000003B, ZAP_TYPE(STRUCT), 0, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(NULLABLE), \ + ZAP_EMPTY_DEFAULT() }, /* SecurityPolicy */ \ + { 0x0000003C, ZAP_TYPE(OCTET_STRING), 5, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(NULLABLE), \ + ZAP_EMPTY_DEFAULT() }, /* ChannelPage0Mask */ \ + { 0x0000003D, ZAP_TYPE(STRUCT), 0, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(NULLABLE), \ + ZAP_EMPTY_DEFAULT() }, /* OperationalDatasetComponents */ \ + { 0x0000003E, ZAP_TYPE(ARRAY), 0, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), \ + ZAP_EMPTY_DEFAULT() }, /* ActiveNetworkFaultsList */ \ + { 0x0000FFFC, ZAP_TYPE(BITMAP32), 4, 0, ZAP_SIMPLE_DEFAULT(0x000F) }, /* FeatureMap */ \ + { 0x0000FFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(1) }, /* ClusterRevision */ \ + \ + /* Endpoint: 0, Cluster: WiFi Network Diagnostics (server) */ \ + { 0x00000000, ZAP_TYPE(OCTET_STRING), 7, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(NULLABLE), \ + ZAP_EMPTY_DEFAULT() }, /* bssid */ \ + { 0x00000001, ZAP_TYPE(ENUM8), 1, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(NULLABLE), \ + ZAP_EMPTY_DEFAULT() }, /* SecurityType */ \ + { 0x00000002, ZAP_TYPE(ENUM8), 1, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(NULLABLE), \ + ZAP_EMPTY_DEFAULT() }, /* WiFiVersion */ \ + { 0x00000003, ZAP_TYPE(INT16U), 2, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(NULLABLE), \ + ZAP_EMPTY_DEFAULT() }, /* ChannelNumber */ \ + { 0x00000004, ZAP_TYPE(INT8S), 1, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(NULLABLE), \ + ZAP_EMPTY_DEFAULT() }, /* Rssi */ \ + { 0x00000005, ZAP_TYPE(INT32U), 4, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(NULLABLE), \ + ZAP_EMPTY_DEFAULT() }, /* BeaconLostCount */ \ + { 0x00000006, ZAP_TYPE(INT32U), 4, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(NULLABLE), \ + ZAP_EMPTY_DEFAULT() }, /* BeaconRxCount */ \ + { 0x00000007, ZAP_TYPE(INT32U), 4, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(NULLABLE), \ + ZAP_EMPTY_DEFAULT() }, /* PacketMulticastRxCount */ \ + { 0x00000008, ZAP_TYPE(INT32U), 4, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(NULLABLE), \ + ZAP_EMPTY_DEFAULT() }, /* PacketMulticastTxCount */ \ + { 0x00000009, ZAP_TYPE(INT32U), 4, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(NULLABLE), \ + ZAP_EMPTY_DEFAULT() }, /* PacketUnicastRxCount */ \ + { 0x0000000A, ZAP_TYPE(INT32U), 4, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(NULLABLE), \ + ZAP_EMPTY_DEFAULT() }, /* PacketUnicastTxCount */ \ + { 0x0000000B, ZAP_TYPE(INT64U), 8, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(NULLABLE), \ + ZAP_EMPTY_DEFAULT() }, /* CurrentMaxRate */ \ + { 0x0000000C, ZAP_TYPE(INT64U), 8, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(NULLABLE), \ + ZAP_EMPTY_DEFAULT() }, /* OverrunCount */ \ + { 0x0000FFFC, ZAP_TYPE(BITMAP32), 4, 0, ZAP_SIMPLE_DEFAULT(3) }, /* FeatureMap */ \ + { 0x0000FFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(1) }, /* ClusterRevision */ \ + \ + /* Endpoint: 0, Cluster: Ethernet Network Diagnostics (server) */ \ + { 0x00000000, ZAP_TYPE(ENUM8), 1, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(NULLABLE), \ + ZAP_EMPTY_DEFAULT() }, /* PHYRate */ \ + { 0x00000001, ZAP_TYPE(BOOLEAN), 1, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(NULLABLE), \ + ZAP_EMPTY_DEFAULT() }, /* FullDuplex */ \ + { 0x00000002, ZAP_TYPE(INT64U), 8, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* PacketRxCount */ \ + { 0x00000003, ZAP_TYPE(INT64U), 8, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* PacketTxCount */ \ + { 0x00000004, ZAP_TYPE(INT64U), 8, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* TxErrCount */ \ + { 0x00000005, ZAP_TYPE(INT64U), 8, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* CollisionCount */ \ + { 0x00000006, ZAP_TYPE(INT64U), 8, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* OverrunCount */ \ + { 0x00000007, ZAP_TYPE(BOOLEAN), 1, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(NULLABLE), \ + ZAP_EMPTY_DEFAULT() }, /* CarrierDetect */ \ + { 0x00000008, ZAP_TYPE(INT64U), 8, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* TimeSinceReset */ \ + { 0x0000FFFC, ZAP_TYPE(BITMAP32), 4, 0, ZAP_SIMPLE_DEFAULT(3) }, /* FeatureMap */ \ + { 0x0000FFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(1) }, /* ClusterRevision */ \ + \ + /* Endpoint: 0, Cluster: AdministratorCommissioning (server) */ \ + { 0x00000000, ZAP_TYPE(ENUM8), 1, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* WindowStatus */ \ + { 0x00000001, ZAP_TYPE(FABRIC_IDX), 1, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(NULLABLE), \ + ZAP_EMPTY_DEFAULT() }, /* AdminFabricIndex */ \ + { 0x00000002, ZAP_TYPE(INT16U), 2, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(NULLABLE), \ + ZAP_EMPTY_DEFAULT() }, /* AdminVendorId */ \ + { 0x0000FFFC, ZAP_TYPE(BITMAP32), 4, 0, ZAP_SIMPLE_DEFAULT(0) }, /* FeatureMap */ \ + { 0x0000FFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(1) }, /* ClusterRevision */ \ + \ + /* Endpoint: 0, Cluster: Operational Credentials (server) */ \ + { 0x00000000, ZAP_TYPE(ARRAY), 0, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* NOCs */ \ + { 0x00000001, ZAP_TYPE(ARRAY), 0, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* Fabrics */ \ + { 0x00000002, ZAP_TYPE(INT8U), 1, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* SupportedFabrics */ \ + { 0x00000003, ZAP_TYPE(INT8U), 1, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), \ + ZAP_EMPTY_DEFAULT() }, /* CommissionedFabrics */ \ + { 0x00000004, ZAP_TYPE(ARRAY), 0, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), \ + ZAP_EMPTY_DEFAULT() }, /* TrustedRootCertificates */ \ + { 0x00000005, ZAP_TYPE(INT8U), 1, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), \ + ZAP_EMPTY_DEFAULT() }, /* CurrentFabricIndex */ \ + { 0x0000FFFC, ZAP_TYPE(BITMAP32), 4, 0, ZAP_SIMPLE_DEFAULT(0) }, /* FeatureMap */ \ + { 0x0000FFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(1) }, /* ClusterRevision */ \ + \ + /* Endpoint: 0, Cluster: Group Key Management (server) */ \ + { 0x00000000, ZAP_TYPE(ARRAY), 0, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(WRITABLE), \ + ZAP_EMPTY_DEFAULT() }, /* GroupKeyMap */ \ + { 0x00000001, ZAP_TYPE(ARRAY), 0, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* GroupTable */ \ + { 0x00000002, ZAP_TYPE(INT16U), 2, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), \ + ZAP_EMPTY_DEFAULT() }, /* MaxGroupsPerFabric */ \ + { 0x00000003, ZAP_TYPE(INT16U), 2, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), \ + ZAP_EMPTY_DEFAULT() }, /* MaxGroupKeysPerFabric */ \ + { 0x0000FFFC, ZAP_TYPE(BITMAP32), 4, 0, ZAP_SIMPLE_DEFAULT(0) }, /* FeatureMap */ \ + { 0x0000FFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(1) }, /* ClusterRevision */ \ + \ + /* Endpoint: 0, Cluster: Fixed Label (server) */ \ + { 0x00000000, ZAP_TYPE(ARRAY), 0, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* label list */ \ + { 0x0000FFFC, ZAP_TYPE(BITMAP32), 4, 0, ZAP_SIMPLE_DEFAULT(0) }, /* FeatureMap */ \ + { 0x0000FFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(1) }, /* ClusterRevision */ \ + \ + /* Endpoint: 0, Cluster: User Label (server) */ \ + { 0x00000000, ZAP_TYPE(ARRAY), 0, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(WRITABLE), \ + ZAP_EMPTY_DEFAULT() }, /* label list */ \ + { 0x0000FFFC, ZAP_TYPE(BITMAP32), 4, 0, ZAP_SIMPLE_DEFAULT(0) }, /* FeatureMap */ \ + { 0x0000FFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(1) }, /* ClusterRevision */ \ + \ + /* Endpoint: 1, Cluster: Identify (server) */ \ + { 0x00000000, ZAP_TYPE(INT16U), 2, ZAP_ATTRIBUTE_MASK(WRITABLE), ZAP_SIMPLE_DEFAULT(0x0000) }, /* identify time */ \ + { 0x00000001, ZAP_TYPE(ENUM8), 1, 0, ZAP_SIMPLE_DEFAULT(0x0) }, /* identify type */ \ + { 0x0000FFFC, ZAP_TYPE(BITMAP32), 4, 0, ZAP_SIMPLE_DEFAULT(0) }, /* FeatureMap */ \ + { 0x0000FFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(4) }, /* ClusterRevision */ \ + \ + /* Endpoint: 1, Cluster: Descriptor (server) */ \ + { 0x00000000, ZAP_TYPE(ARRAY), 0, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* DeviceTypeList */ \ + { 0x00000001, ZAP_TYPE(ARRAY), 0, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* ServerList */ \ + { 0x00000002, ZAP_TYPE(ARRAY), 0, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* ClientList */ \ + { 0x00000003, ZAP_TYPE(ARRAY), 0, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* PartsList */ \ + { 0x0000FFFC, ZAP_TYPE(BITMAP32), 4, 0, ZAP_SIMPLE_DEFAULT(0) }, /* FeatureMap */ \ + { 0x0000FFFD, ZAP_TYPE(INT16U), 2, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* ClusterRevision */ \ + \ + /* Endpoint: 1, Cluster: Boolean State (server) */ \ + { 0x00000000, ZAP_TYPE(BOOLEAN), 1, 0, ZAP_SIMPLE_DEFAULT(0) }, /* StateValue */ \ + { 0x0000FFFC, ZAP_TYPE(BITMAP32), 4, 0, ZAP_SIMPLE_DEFAULT(0) }, /* FeatureMap */ \ + { 0x0000FFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(1) }, /* ClusterRevision */ \ + \ + /* Endpoint: 1, Cluster: Occupancy Sensing (server) */ \ + { 0x00000000, ZAP_TYPE(BITMAP8), 1, 0, ZAP_EMPTY_DEFAULT() }, /* occupancy */ \ + { 0x00000001, ZAP_TYPE(ENUM8), 1, 0, ZAP_EMPTY_DEFAULT() }, /* occupancy sensor type */ \ + { 0x00000002, ZAP_TYPE(BITMAP8), 1, 0, ZAP_EMPTY_DEFAULT() }, /* occupancy sensor type bitmap */ \ + { 0x0000FFFC, ZAP_TYPE(BITMAP32), 4, 0, ZAP_SIMPLE_DEFAULT(0) }, /* FeatureMap */ \ + { 0x0000FFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(3) }, /* ClusterRevision */ \ + } + +// This is an array of EmberAfCluster structures. +#define ZAP_ATTRIBUTE_INDEX(index) (&generatedAttributes[index]) + +#define ZAP_GENERATED_COMMANDS_INDEX(index) ((chip::CommandId *) (&generatedCommands[index])) + +// Cluster function static arrays +#define GENERATED_FUNCTION_ARRAYS \ + const EmberAfGenericClusterFunction chipFuncArrayGroupsServer[] = { \ + (EmberAfGenericClusterFunction) emberAfGroupsClusterServerInitCallback, \ + }; \ + const EmberAfGenericClusterFunction chipFuncArrayBasicServer[] = { \ + (EmberAfGenericClusterFunction) emberAfBasicClusterServerInitCallback, \ + }; \ + const EmberAfGenericClusterFunction chipFuncArrayLocalizationConfigurationServer[] = { \ + (EmberAfGenericClusterFunction) emberAfLocalizationConfigurationClusterServerInitCallback, \ + (EmberAfGenericClusterFunction) MatterLocalizationConfigurationClusterServerPreAttributeChangedCallback, \ + }; \ + const EmberAfGenericClusterFunction chipFuncArrayTimeFormatLocalizationServer[] = { \ + (EmberAfGenericClusterFunction) emberAfTimeFormatLocalizationClusterServerInitCallback, \ + (EmberAfGenericClusterFunction) MatterTimeFormatLocalizationClusterServerPreAttributeChangedCallback, \ + }; \ + const EmberAfGenericClusterFunction chipFuncArrayIdentifyServer[] = { \ + (EmberAfGenericClusterFunction) emberAfIdentifyClusterServerInitCallback, \ + (EmberAfGenericClusterFunction) MatterIdentifyClusterServerAttributeChangedCallback, \ + }; \ + const EmberAfGenericClusterFunction chipFuncArrayOccupancySensingServer[] = { \ + (EmberAfGenericClusterFunction) emberAfOccupancySensingClusterServerInitCallback, \ + }; + +// clang-format off +#define GENERATED_COMMANDS { \ + /* Endpoint: 0, Cluster: Groups (server) */\ + /* AcceptedCommandList (index=0) */ \ + 0x00000000 /* AddGroup */, \ + 0x00000001 /* ViewGroup */, \ + 0x00000002 /* GetGroupMembership */, \ + 0x00000003 /* RemoveGroup */, \ + 0x00000004 /* RemoveAllGroups */, \ + 0x00000005 /* AddGroupIfIdentifying */, \ + chip::kInvalidCommandId /* end of list */, \ + /* GeneratedCommandList (index=7)*/ \ + 0x00000000 /* AddGroupResponse */, \ + 0x00000001 /* ViewGroupResponse */, \ + 0x00000002 /* GetGroupMembershipResponse */, \ + 0x00000003 /* RemoveGroupResponse */, \ + chip::kInvalidCommandId /* end of list */, \ + /* Endpoint: 0, Cluster: OTA Software Update Requestor (server) */\ + /* AcceptedCommandList (index=12) */ \ + 0x00000000 /* AnnounceOtaProvider */, \ + chip::kInvalidCommandId /* end of list */, \ + /* Endpoint: 0, Cluster: General Commissioning (server) */\ + /* AcceptedCommandList (index=14) */ \ + 0x00000000 /* ArmFailSafe */, \ + 0x00000002 /* SetRegulatoryConfig */, \ + 0x00000004 /* CommissioningComplete */, \ + chip::kInvalidCommandId /* end of list */, \ + /* GeneratedCommandList (index=18)*/ \ + 0x00000001 /* ArmFailSafeResponse */, \ + 0x00000003 /* SetRegulatoryConfigResponse */, \ + 0x00000005 /* CommissioningCompleteResponse */, \ + chip::kInvalidCommandId /* end of list */, \ + /* Endpoint: 0, Cluster: Network Commissioning (server) */\ + /* AcceptedCommandList (index=22) */ \ + 0x00000000 /* ScanNetworks */, \ + 0x00000002 /* AddOrUpdateWiFiNetwork */, \ + 0x00000003 /* AddOrUpdateThreadNetwork */, \ + 0x00000004 /* RemoveNetwork */, \ + 0x00000006 /* ConnectNetwork */, \ + 0x00000008 /* ReorderNetwork */, \ + chip::kInvalidCommandId /* end of list */, \ + /* GeneratedCommandList (index=29)*/ \ + 0x00000001 /* ScanNetworksResponse */, \ + 0x00000005 /* NetworkConfigResponse */, \ + 0x00000007 /* ConnectNetworkResponse */, \ + chip::kInvalidCommandId /* end of list */, \ + /* Endpoint: 0, Cluster: Diagnostic Logs (server) */\ + /* AcceptedCommandList (index=33) */ \ + 0x00000000 /* RetrieveLogsRequest */, \ + chip::kInvalidCommandId /* end of list */, \ + /* GeneratedCommandList (index=35)*/ \ + 0x00000001 /* RetrieveLogsResponse */, \ + chip::kInvalidCommandId /* end of list */, \ + /* Endpoint: 0, Cluster: General Diagnostics (server) */\ + /* AcceptedCommandList (index=37) */ \ + 0x00000000 /* TestEventTrigger */, \ + chip::kInvalidCommandId /* end of list */, \ + /* Endpoint: 0, Cluster: Software Diagnostics (server) */\ + /* AcceptedCommandList (index=39) */ \ + 0x00000000 /* ResetWatermarks */, \ + chip::kInvalidCommandId /* end of list */, \ + /* Endpoint: 0, Cluster: Thread Network Diagnostics (server) */\ + /* AcceptedCommandList (index=41) */ \ + 0x00000000 /* ResetCounts */, \ + chip::kInvalidCommandId /* end of list */, \ + /* Endpoint: 0, Cluster: WiFi Network Diagnostics (server) */\ + /* AcceptedCommandList (index=43) */ \ + 0x00000000 /* ResetCounts */, \ + chip::kInvalidCommandId /* end of list */, \ + /* Endpoint: 0, Cluster: Ethernet Network Diagnostics (server) */\ + /* AcceptedCommandList (index=45) */ \ + 0x00000000 /* ResetCounts */, \ + chip::kInvalidCommandId /* end of list */, \ + /* Endpoint: 0, Cluster: AdministratorCommissioning (server) */\ + /* AcceptedCommandList (index=47) */ \ + 0x00000000 /* OpenCommissioningWindow */, \ + 0x00000001 /* OpenBasicCommissioningWindow */, \ + 0x00000002 /* RevokeCommissioning */, \ + chip::kInvalidCommandId /* end of list */, \ + /* Endpoint: 0, Cluster: Operational Credentials (server) */\ + /* AcceptedCommandList (index=51) */ \ + 0x00000000 /* AttestationRequest */, \ + 0x00000002 /* CertificateChainRequest */, \ + 0x00000004 /* CSRRequest */, \ + 0x00000006 /* AddNOC */, \ + 0x00000007 /* UpdateNOC */, \ + 0x00000009 /* UpdateFabricLabel */, \ + 0x0000000A /* RemoveFabric */, \ + 0x0000000B /* AddTrustedRootCertificate */, \ + chip::kInvalidCommandId /* end of list */, \ + /* GeneratedCommandList (index=60)*/ \ + 0x00000001 /* AttestationResponse */, \ + 0x00000003 /* CertificateChainResponse */, \ + 0x00000005 /* CSRResponse */, \ + 0x00000008 /* NOCResponse */, \ + chip::kInvalidCommandId /* end of list */, \ + /* Endpoint: 0, Cluster: Group Key Management (server) */\ + /* AcceptedCommandList (index=65) */ \ + 0x00000000 /* KeySetWrite */, \ + 0x00000001 /* KeySetRead */, \ + 0x00000003 /* KeySetRemove */, \ + 0x00000004 /* KeySetReadAllIndices */, \ + chip::kInvalidCommandId /* end of list */, \ + /* GeneratedCommandList (index=70)*/ \ + 0x00000002 /* KeySetReadResponse */, \ + 0x00000005 /* KeySetReadAllIndicesResponse */, \ + chip::kInvalidCommandId /* end of list */, \ + /* Endpoint: 1, Cluster: Identify (server) */\ + /* AcceptedCommandList (index=73) */ \ + 0x00000000 /* Identify */, \ + 0x00000040 /* TriggerEffect */, \ + chip::kInvalidCommandId /* end of list */, \ +} + +// clang-format on + +#define ZAP_CLUSTER_MASK(mask) CLUSTER_MASK_##mask +#define GENERATED_CLUSTER_COUNT 25 + +// clang-format off +#define GENERATED_CLUSTERS { \ + { \ + /* Endpoint: 0, Cluster: Groups (server) */ \ + .clusterId = 0x00000004, \ + .attributes = ZAP_ATTRIBUTE_INDEX(0), \ + .attributeCount = 3, \ + .clusterSize = 7, \ + .mask = ZAP_CLUSTER_MASK(SERVER) | ZAP_CLUSTER_MASK(INIT_FUNCTION), \ + .functions = chipFuncArrayGroupsServer, \ + .acceptedCommandList = ZAP_GENERATED_COMMANDS_INDEX( 0 ) ,\ + .generatedCommandList = ZAP_GENERATED_COMMANDS_INDEX( 7 ) ,\ + },\ + { \ + /* Endpoint: 0, Cluster: Descriptor (server) */ \ + .clusterId = 0x0000001D, \ + .attributes = ZAP_ATTRIBUTE_INDEX(3), \ + .attributeCount = 6, \ + .clusterSize = 4, \ + .mask = ZAP_CLUSTER_MASK(SERVER), \ + .functions = NULL, \ + .acceptedCommandList = nullptr ,\ + .generatedCommandList = nullptr ,\ + },\ + { \ + /* Endpoint: 0, Cluster: Access Control (server) */ \ + .clusterId = 0x0000001F, \ + .attributes = ZAP_ATTRIBUTE_INDEX(9), \ + .attributeCount = 7, \ + .clusterSize = 6, \ + .mask = ZAP_CLUSTER_MASK(SERVER), \ + .functions = NULL, \ + .acceptedCommandList = nullptr ,\ + .generatedCommandList = nullptr ,\ + },\ + { \ + /* Endpoint: 0, Cluster: Basic (server) */ \ + .clusterId = 0x00000028, \ + .attributes = ZAP_ATTRIBUTE_INDEX(16), \ + .attributeCount = 22, \ + .clusterSize = 41, \ + .mask = ZAP_CLUSTER_MASK(SERVER) | ZAP_CLUSTER_MASK(INIT_FUNCTION), \ + .functions = chipFuncArrayBasicServer, \ + .acceptedCommandList = nullptr ,\ + .generatedCommandList = nullptr ,\ + },\ + { \ + /* Endpoint: 0, Cluster: OTA Software Update Provider (client) */ \ + .clusterId = 0x00000029, \ + .attributes = ZAP_ATTRIBUTE_INDEX(38), \ + .attributeCount = 0, \ + .clusterSize = 0, \ + .mask = ZAP_CLUSTER_MASK(CLIENT), \ + .functions = NULL, \ + .acceptedCommandList = nullptr ,\ + .generatedCommandList = nullptr ,\ + },\ + { \ + /* Endpoint: 0, Cluster: OTA Software Update Requestor (server) */ \ + .clusterId = 0x0000002A, \ + .attributes = ZAP_ATTRIBUTE_INDEX(38), \ + .attributeCount = 6, \ + .clusterSize = 9, \ + .mask = ZAP_CLUSTER_MASK(SERVER), \ + .functions = NULL, \ + .acceptedCommandList = ZAP_GENERATED_COMMANDS_INDEX( 12 ) ,\ + .generatedCommandList = nullptr ,\ + },\ + { \ + /* Endpoint: 0, Cluster: Localization Configuration (server) */ \ + .clusterId = 0x0000002B, \ + .attributes = ZAP_ATTRIBUTE_INDEX(44), \ + .attributeCount = 4, \ + .clusterSize = 42, \ + .mask = ZAP_CLUSTER_MASK(SERVER) | ZAP_CLUSTER_MASK(INIT_FUNCTION) | ZAP_CLUSTER_MASK(PRE_ATTRIBUTE_CHANGED_FUNCTION), \ + .functions = chipFuncArrayLocalizationConfigurationServer, \ + .acceptedCommandList = nullptr ,\ + .generatedCommandList = nullptr ,\ + },\ + { \ + /* Endpoint: 0, Cluster: Time Format Localization (server) */ \ + .clusterId = 0x0000002C, \ + .attributes = ZAP_ATTRIBUTE_INDEX(48), \ + .attributeCount = 5, \ + .clusterSize = 8, \ + .mask = ZAP_CLUSTER_MASK(SERVER) | ZAP_CLUSTER_MASK(INIT_FUNCTION) | ZAP_CLUSTER_MASK(PRE_ATTRIBUTE_CHANGED_FUNCTION), \ + .functions = chipFuncArrayTimeFormatLocalizationServer, \ + .acceptedCommandList = nullptr ,\ + .generatedCommandList = nullptr ,\ + },\ + { \ + /* Endpoint: 0, Cluster: General Commissioning (server) */ \ + .clusterId = 0x00000030, \ + .attributes = ZAP_ATTRIBUTE_INDEX(53), \ + .attributeCount = 7, \ + .clusterSize = 14, \ + .mask = ZAP_CLUSTER_MASK(SERVER), \ + .functions = NULL, \ + .acceptedCommandList = ZAP_GENERATED_COMMANDS_INDEX( 14 ) ,\ + .generatedCommandList = ZAP_GENERATED_COMMANDS_INDEX( 18 ) ,\ + },\ + { \ + /* Endpoint: 0, Cluster: Network Commissioning (server) */ \ + .clusterId = 0x00000031, \ + .attributes = ZAP_ATTRIBUTE_INDEX(60), \ + .attributeCount = 10, \ + .clusterSize = 48, \ + .mask = ZAP_CLUSTER_MASK(SERVER), \ + .functions = NULL, \ + .acceptedCommandList = ZAP_GENERATED_COMMANDS_INDEX( 22 ) ,\ + .generatedCommandList = ZAP_GENERATED_COMMANDS_INDEX( 29 ) ,\ + },\ + { \ + /* Endpoint: 0, Cluster: Diagnostic Logs (server) */ \ + .clusterId = 0x00000032, \ + .attributes = ZAP_ATTRIBUTE_INDEX(70), \ + .attributeCount = 2, \ + .clusterSize = 6, \ + .mask = ZAP_CLUSTER_MASK(SERVER), \ + .functions = NULL, \ + .acceptedCommandList = ZAP_GENERATED_COMMANDS_INDEX( 33 ) ,\ + .generatedCommandList = ZAP_GENERATED_COMMANDS_INDEX( 35 ) ,\ + },\ + { \ + /* Endpoint: 0, Cluster: General Diagnostics (server) */ \ + .clusterId = 0x00000033, \ + .attributes = ZAP_ATTRIBUTE_INDEX(72), \ + .attributeCount = 11, \ + .clusterSize = 6, \ + .mask = ZAP_CLUSTER_MASK(SERVER), \ + .functions = NULL, \ + .acceptedCommandList = ZAP_GENERATED_COMMANDS_INDEX( 37 ) ,\ + .generatedCommandList = nullptr ,\ + },\ + { \ + /* Endpoint: 0, Cluster: Software Diagnostics (server) */ \ + .clusterId = 0x00000034, \ + .attributes = ZAP_ATTRIBUTE_INDEX(83), \ + .attributeCount = 6, \ + .clusterSize = 6, \ + .mask = ZAP_CLUSTER_MASK(SERVER), \ + .functions = NULL, \ + .acceptedCommandList = ZAP_GENERATED_COMMANDS_INDEX( 39 ) ,\ + .generatedCommandList = nullptr ,\ + },\ + { \ + /* Endpoint: 0, Cluster: Thread Network Diagnostics (server) */ \ + .clusterId = 0x00000035, \ + .attributes = ZAP_ATTRIBUTE_INDEX(89), \ + .attributeCount = 65, \ + .clusterSize = 6, \ + .mask = ZAP_CLUSTER_MASK(SERVER), \ + .functions = NULL, \ + .acceptedCommandList = ZAP_GENERATED_COMMANDS_INDEX( 41 ) ,\ + .generatedCommandList = nullptr ,\ + },\ + { \ + /* Endpoint: 0, Cluster: WiFi Network Diagnostics (server) */ \ + .clusterId = 0x00000036, \ + .attributes = ZAP_ATTRIBUTE_INDEX(154), \ + .attributeCount = 15, \ + .clusterSize = 6, \ + .mask = ZAP_CLUSTER_MASK(SERVER), \ + .functions = NULL, \ + .acceptedCommandList = ZAP_GENERATED_COMMANDS_INDEX( 43 ) ,\ + .generatedCommandList = nullptr ,\ + },\ + { \ + /* Endpoint: 0, Cluster: Ethernet Network Diagnostics (server) */ \ + .clusterId = 0x00000037, \ + .attributes = ZAP_ATTRIBUTE_INDEX(169), \ + .attributeCount = 11, \ + .clusterSize = 6, \ + .mask = ZAP_CLUSTER_MASK(SERVER), \ + .functions = NULL, \ + .acceptedCommandList = ZAP_GENERATED_COMMANDS_INDEX( 45 ) ,\ + .generatedCommandList = nullptr ,\ + },\ + { \ + /* Endpoint: 0, Cluster: AdministratorCommissioning (server) */ \ + .clusterId = 0x0000003C, \ + .attributes = ZAP_ATTRIBUTE_INDEX(180), \ + .attributeCount = 5, \ + .clusterSize = 6, \ + .mask = ZAP_CLUSTER_MASK(SERVER), \ + .functions = NULL, \ + .acceptedCommandList = ZAP_GENERATED_COMMANDS_INDEX( 47 ) ,\ + .generatedCommandList = nullptr ,\ + },\ + { \ + /* Endpoint: 0, Cluster: Operational Credentials (server) */ \ + .clusterId = 0x0000003E, \ + .attributes = ZAP_ATTRIBUTE_INDEX(185), \ + .attributeCount = 8, \ + .clusterSize = 6, \ + .mask = ZAP_CLUSTER_MASK(SERVER), \ + .functions = NULL, \ + .acceptedCommandList = ZAP_GENERATED_COMMANDS_INDEX( 51 ) ,\ + .generatedCommandList = ZAP_GENERATED_COMMANDS_INDEX( 60 ) ,\ + },\ + { \ + /* Endpoint: 0, Cluster: Group Key Management (server) */ \ + .clusterId = 0x0000003F, \ + .attributes = ZAP_ATTRIBUTE_INDEX(193), \ + .attributeCount = 6, \ + .clusterSize = 6, \ + .mask = ZAP_CLUSTER_MASK(SERVER), \ + .functions = NULL, \ + .acceptedCommandList = ZAP_GENERATED_COMMANDS_INDEX( 65 ) ,\ + .generatedCommandList = ZAP_GENERATED_COMMANDS_INDEX( 70 ) ,\ + },\ + { \ + /* Endpoint: 0, Cluster: Fixed Label (server) */ \ + .clusterId = 0x00000040, \ + .attributes = ZAP_ATTRIBUTE_INDEX(199), \ + .attributeCount = 3, \ + .clusterSize = 6, \ + .mask = ZAP_CLUSTER_MASK(SERVER), \ + .functions = NULL, \ + .acceptedCommandList = nullptr ,\ + .generatedCommandList = nullptr ,\ + },\ + { \ + /* Endpoint: 0, Cluster: User Label (server) */ \ + .clusterId = 0x00000041, \ + .attributes = ZAP_ATTRIBUTE_INDEX(202), \ + .attributeCount = 3, \ + .clusterSize = 6, \ + .mask = ZAP_CLUSTER_MASK(SERVER), \ + .functions = NULL, \ + .acceptedCommandList = nullptr ,\ + .generatedCommandList = nullptr ,\ + },\ + { \ + /* Endpoint: 1, Cluster: Identify (server) */ \ + .clusterId = 0x00000003, \ + .attributes = ZAP_ATTRIBUTE_INDEX(205), \ + .attributeCount = 4, \ + .clusterSize = 9, \ + .mask = ZAP_CLUSTER_MASK(SERVER) | ZAP_CLUSTER_MASK(INIT_FUNCTION) | ZAP_CLUSTER_MASK(ATTRIBUTE_CHANGED_FUNCTION), \ + .functions = chipFuncArrayIdentifyServer, \ + .acceptedCommandList = ZAP_GENERATED_COMMANDS_INDEX( 73 ) ,\ + .generatedCommandList = nullptr ,\ + },\ + { \ + /* Endpoint: 1, Cluster: Descriptor (server) */ \ + .clusterId = 0x0000001D, \ + .attributes = ZAP_ATTRIBUTE_INDEX(209), \ + .attributeCount = 6, \ + .clusterSize = 4, \ + .mask = ZAP_CLUSTER_MASK(SERVER), \ + .functions = NULL, \ + .acceptedCommandList = nullptr ,\ + .generatedCommandList = nullptr ,\ + },\ + { \ + /* Endpoint: 1, Cluster: Boolean State (server) */ \ + .clusterId = 0x00000045, \ + .attributes = ZAP_ATTRIBUTE_INDEX(215), \ + .attributeCount = 3, \ + .clusterSize = 7, \ + .mask = ZAP_CLUSTER_MASK(SERVER), \ + .functions = NULL, \ + .acceptedCommandList = nullptr ,\ + .generatedCommandList = nullptr ,\ + },\ + { \ + /* Endpoint: 1, Cluster: Occupancy Sensing (server) */ \ + .clusterId = 0x00000406, \ + .attributes = ZAP_ATTRIBUTE_INDEX(218), \ + .attributeCount = 5, \ + .clusterSize = 9, \ + .mask = ZAP_CLUSTER_MASK(SERVER) | ZAP_CLUSTER_MASK(INIT_FUNCTION), \ + .functions = chipFuncArrayOccupancySensingServer, \ + .acceptedCommandList = nullptr ,\ + .generatedCommandList = nullptr ,\ + },\ +} + +// clang-format on + +#define ZAP_CLUSTER_INDEX(index) (&generatedClusters[index]) + +#define ZAP_FIXED_ENDPOINT_DATA_VERSION_COUNT 24 + +// This is an array of EmberAfEndpointType structures. +#define GENERATED_ENDPOINT_TYPES \ + { \ + { ZAP_CLUSTER_INDEX(0), 21, 245 }, { ZAP_CLUSTER_INDEX(21), 4, 29 }, \ + } + +// Largest attribute size is needed for various buffers +#define ATTRIBUTE_LARGEST (259) + +static_assert(ATTRIBUTE_LARGEST <= CHIP_CONFIG_MAX_ATTRIBUTE_STORE_ELEMENT_SIZE, "ATTRIBUTE_LARGEST larger than expected"); + +// Total size of singleton attributes +#define ATTRIBUTE_SINGLETONS_SIZE (37) + +// Total size of attribute storage +#define ATTRIBUTE_MAX_SIZE (274) + +// Number of fixed endpoints +#define FIXED_ENDPOINT_COUNT (2) + +// Array of endpoints that are supported, the data inside +// the array is the endpoint number. +#define FIXED_ENDPOINT_ARRAY \ + { \ + 0x0000, 0x0001 \ + } + +// Array of profile ids +#define FIXED_PROFILE_IDS \ + { \ + 0x0103, 0x0103 \ + } + +// Array of device types +#define FIXED_DEVICE_TYPES \ + { \ + { 0x0016, 1 }, { 0x0015, 1 } \ + } + +// Array of device type offsets +#define FIXED_DEVICE_TYPE_OFFSETS \ + { \ + 0, 1 \ + } + +// Array of device type lengths +#define FIXED_DEVICE_TYPE_LENGTHS \ + { \ + 1, 1 \ + } + +// Array of endpoint types supported on each endpoint +#define FIXED_ENDPOINT_TYPES \ + { \ + 0, 1 \ + } + +// Array of networks supported on each endpoint +#define FIXED_NETWORKS \ + { \ + 0, 0 \ + } diff --git a/zzz_generated/contact-sensor-app/zap-generated/gen_config.h b/zzz_generated/contact-sensor-app/zap-generated/gen_config.h new file mode 100644 index 00000000000000..e93e4b72742c90 --- /dev/null +++ b/zzz_generated/contact-sensor-app/zap-generated/gen_config.h @@ -0,0 +1,176 @@ +/* + * + * 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 + +// Prevent multiple inclusion +#pragma once + +// User options for plugin Binding Table Library +#define EMBER_BINDING_TABLE_SIZE 10 + +/**** Network Section ****/ +#define EMBER_SUPPORTED_NETWORKS (1) + +#define EMBER_APS_UNICAST_MESSAGE_COUNT 10 + +/**** Cluster endpoint counts ****/ +#define EMBER_AF_IDENTIFY_CLUSTER_SERVER_ENDPOINT_COUNT (1) +#define EMBER_AF_GROUPS_CLUSTER_SERVER_ENDPOINT_COUNT (1) +#define EMBER_AF_DESCRIPTOR_CLUSTER_SERVER_ENDPOINT_COUNT (2) +#define EMBER_AF_ACCESS_CONTROL_CLUSTER_SERVER_ENDPOINT_COUNT (1) +#define EMBER_AF_BASIC_CLUSTER_SERVER_ENDPOINT_COUNT (1) +#define EMBER_AF_OTA_PROVIDER_CLUSTER_CLIENT_ENDPOINT_COUNT (1) +#define EMBER_AF_OTA_REQUESTOR_CLUSTER_SERVER_ENDPOINT_COUNT (1) +#define EMBER_AF_LOCALIZATION_CONFIGURATION_CLUSTER_SERVER_ENDPOINT_COUNT (1) +#define EMBER_AF_TIME_FORMAT_LOCALIZATION_CLUSTER_SERVER_ENDPOINT_COUNT (1) +#define EMBER_AF_GENERAL_COMMISSIONING_CLUSTER_SERVER_ENDPOINT_COUNT (1) +#define EMBER_AF_NETWORK_COMMISSIONING_CLUSTER_SERVER_ENDPOINT_COUNT (1) +#define EMBER_AF_DIAGNOSTIC_LOGS_CLUSTER_SERVER_ENDPOINT_COUNT (1) +#define EMBER_AF_GENERAL_DIAGNOSTICS_CLUSTER_SERVER_ENDPOINT_COUNT (1) +#define EMBER_AF_SOFTWARE_DIAGNOSTICS_CLUSTER_SERVER_ENDPOINT_COUNT (1) +#define EMBER_AF_THREAD_NETWORK_DIAGNOSTICS_CLUSTER_SERVER_ENDPOINT_COUNT (1) +#define EMBER_AF_WIFI_NETWORK_DIAGNOSTICS_CLUSTER_SERVER_ENDPOINT_COUNT (1) +#define EMBER_AF_ETHERNET_NETWORK_DIAGNOSTICS_CLUSTER_SERVER_ENDPOINT_COUNT (1) +#define EMBER_AF_ADMINISTRATOR_COMMISSIONING_CLUSTER_SERVER_ENDPOINT_COUNT (1) +#define EMBER_AF_OPERATIONAL_CREDENTIALS_CLUSTER_SERVER_ENDPOINT_COUNT (1) +#define EMBER_AF_GROUP_KEY_MANAGEMENT_CLUSTER_SERVER_ENDPOINT_COUNT (1) +#define EMBER_AF_FIXED_LABEL_CLUSTER_SERVER_ENDPOINT_COUNT (1) +#define EMBER_AF_USER_LABEL_CLUSTER_SERVER_ENDPOINT_COUNT (1) +#define EMBER_AF_BOOLEAN_STATE_CLUSTER_SERVER_ENDPOINT_COUNT (1) +#define EMBER_AF_OCCUPANCY_SENSING_CLUSTER_SERVER_ENDPOINT_COUNT (1) + +/**** Cluster Plugins ****/ + +// Use this macro to check if the server side of the Identify cluster is included +#define ZCL_USING_IDENTIFY_CLUSTER_SERVER +#define EMBER_AF_PLUGIN_IDENTIFY_SERVER +#define EMBER_AF_PLUGIN_IDENTIFY + +// Use this macro to check if the server side of the Groups cluster is included +#define ZCL_USING_GROUPS_CLUSTER_SERVER +#define EMBER_AF_PLUGIN_GROUPS_SERVER +#define EMBER_AF_PLUGIN_GROUPS + +// Use this macro to check if the server side of the Descriptor cluster is included +#define ZCL_USING_DESCRIPTOR_CLUSTER_SERVER +#define EMBER_AF_PLUGIN_DESCRIPTOR_SERVER +#define EMBER_AF_PLUGIN_DESCRIPTOR + +// Use this macro to check if the server side of the Access Control cluster is included +#define ZCL_USING_ACCESS_CONTROL_CLUSTER_SERVER +#define EMBER_AF_PLUGIN_ACCESS_CONTROL_SERVER +#define EMBER_AF_PLUGIN_ACCESS_CONTROL + +// Use this macro to check if the server side of the Basic cluster is included +#define ZCL_USING_BASIC_CLUSTER_SERVER +#define EMBER_AF_PLUGIN_BASIC_SERVER +#define EMBER_AF_PLUGIN_BASIC + +// Use this macro to check if the client side of the OTA Software Update Provider cluster is included +#define ZCL_USING_OTA_PROVIDER_CLUSTER_CLIENT +#define EMBER_AF_PLUGIN_OTA_SOFTWARE_UPDATE_PROVIDER_CLIENT + +// Use this macro to check if the server side of the OTA Software Update Requestor cluster is included +#define ZCL_USING_OTA_REQUESTOR_CLUSTER_SERVER +#define EMBER_AF_PLUGIN_OTA_SOFTWARE_UPDATE_REQUESTOR_SERVER +#define EMBER_AF_PLUGIN_OTA_SOFTWARE_UPDATE_REQUESTOR + +// Use this macro to check if the server side of the Localization Configuration cluster is included +#define ZCL_USING_LOCALIZATION_CONFIGURATION_CLUSTER_SERVER +#define EMBER_AF_PLUGIN_LOCALIZATION_CONFIGURATION_SERVER +#define EMBER_AF_PLUGIN_LOCALIZATION_CONFIGURATION + +// Use this macro to check if the server side of the Time Format Localization cluster is included +#define ZCL_USING_TIME_FORMAT_LOCALIZATION_CLUSTER_SERVER +#define EMBER_AF_PLUGIN_TIME_FORMAT_LOCALIZATION_SERVER +#define EMBER_AF_PLUGIN_TIME_FORMAT_LOCALIZATION + +// Use this macro to check if the server side of the General Commissioning cluster is included +#define ZCL_USING_GENERAL_COMMISSIONING_CLUSTER_SERVER +#define EMBER_AF_PLUGIN_GENERAL_COMMISSIONING_SERVER +#define EMBER_AF_PLUGIN_GENERAL_COMMISSIONING + +// Use this macro to check if the server side of the Network Commissioning cluster is included +#define ZCL_USING_NETWORK_COMMISSIONING_CLUSTER_SERVER +#define EMBER_AF_PLUGIN_NETWORK_COMMISSIONING_SERVER +#define EMBER_AF_PLUGIN_NETWORK_COMMISSIONING + +// Use this macro to check if the server side of the Diagnostic Logs cluster is included +#define ZCL_USING_DIAGNOSTIC_LOGS_CLUSTER_SERVER +#define EMBER_AF_PLUGIN_DIAGNOSTIC_LOGS_SERVER +#define EMBER_AF_PLUGIN_DIAGNOSTIC_LOGS + +// Use this macro to check if the server side of the General Diagnostics cluster is included +#define ZCL_USING_GENERAL_DIAGNOSTICS_CLUSTER_SERVER +#define EMBER_AF_PLUGIN_GENERAL_DIAGNOSTICS_SERVER +#define EMBER_AF_PLUGIN_GENERAL_DIAGNOSTICS + +// Use this macro to check if the server side of the Software Diagnostics cluster is included +#define ZCL_USING_SOFTWARE_DIAGNOSTICS_CLUSTER_SERVER +#define EMBER_AF_PLUGIN_SOFTWARE_DIAGNOSTICS_SERVER +#define EMBER_AF_PLUGIN_SOFTWARE_DIAGNOSTICS + +// Use this macro to check if the server side of the Thread Network Diagnostics cluster is included +#define ZCL_USING_THREAD_NETWORK_DIAGNOSTICS_CLUSTER_SERVER +#define EMBER_AF_PLUGIN_THREAD_NETWORK_DIAGNOSTICS_SERVER +#define EMBER_AF_PLUGIN_THREAD_NETWORK_DIAGNOSTICS + +// Use this macro to check if the server side of the WiFi Network Diagnostics cluster is included +#define ZCL_USING_WIFI_NETWORK_DIAGNOSTICS_CLUSTER_SERVER +#define EMBER_AF_PLUGIN_WI_FI_NETWORK_DIAGNOSTICS_SERVER +#define EMBER_AF_PLUGIN_WI_FI_NETWORK_DIAGNOSTICS + +// Use this macro to check if the server side of the Ethernet Network Diagnostics cluster is included +#define ZCL_USING_ETHERNET_NETWORK_DIAGNOSTICS_CLUSTER_SERVER +#define EMBER_AF_PLUGIN_ETHERNET_NETWORK_DIAGNOSTICS_SERVER +#define EMBER_AF_PLUGIN_ETHERNET_NETWORK_DIAGNOSTICS + +// Use this macro to check if the server side of the AdministratorCommissioning cluster is included +#define ZCL_USING_ADMINISTRATOR_COMMISSIONING_CLUSTER_SERVER +#define EMBER_AF_PLUGIN_ADMINISTRATOR_COMMISSIONING_SERVER +#define EMBER_AF_PLUGIN_ADMINISTRATOR_COMMISSIONING + +// Use this macro to check if the server side of the Operational Credentials cluster is included +#define ZCL_USING_OPERATIONAL_CREDENTIALS_CLUSTER_SERVER +#define EMBER_AF_PLUGIN_OPERATIONAL_CREDENTIALS_SERVER +#define EMBER_AF_PLUGIN_OPERATIONAL_CREDENTIALS + +// Use this macro to check if the server side of the Group Key Management cluster is included +#define ZCL_USING_GROUP_KEY_MANAGEMENT_CLUSTER_SERVER +#define EMBER_AF_PLUGIN_GROUP_KEY_MANAGEMENT_SERVER +#define EMBER_AF_PLUGIN_GROUP_KEY_MANAGEMENT + +// Use this macro to check if the server side of the Fixed Label cluster is included +#define ZCL_USING_FIXED_LABEL_CLUSTER_SERVER +#define EMBER_AF_PLUGIN_FIXED_LABEL_SERVER +#define EMBER_AF_PLUGIN_FIXED_LABEL + +// Use this macro to check if the server side of the User Label cluster is included +#define ZCL_USING_USER_LABEL_CLUSTER_SERVER +#define EMBER_AF_PLUGIN_USER_LABEL_SERVER +#define EMBER_AF_PLUGIN_USER_LABEL + +// Use this macro to check if the server side of the Boolean State cluster is included +#define ZCL_USING_BOOLEAN_STATE_CLUSTER_SERVER +#define EMBER_AF_PLUGIN_BOOLEAN_STATE_SERVER +#define EMBER_AF_PLUGIN_BOOLEAN_STATE + +// Use this macro to check if the server side of the Occupancy Sensing cluster is included +#define ZCL_USING_OCCUPANCY_SENSING_CLUSTER_SERVER +#define EMBER_AF_PLUGIN_OCCUPANCY_SENSING_SERVER +#define EMBER_AF_PLUGIN_OCCUPANCY_SENSING diff --git a/zzz_generated/contact-sensor-app/zap-generated/gen_tokens.h b/zzz_generated/contact-sensor-app/zap-generated/gen_tokens.h new file mode 100644 index 00000000000000..dcc229f5b2c306 --- /dev/null +++ b/zzz_generated/contact-sensor-app/zap-generated/gen_tokens.h @@ -0,0 +1,45 @@ +/* + * + * 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 + +// Prevent multiple inclusion +#pragma once + +// This file contains the tokens for attributes stored in flash + +// Identifier tags for tokens + +// Types for the tokens +#ifdef DEFINETYPES +#endif // DEFINETYPES + +// Actual token definitions +#ifdef DEFINETOKENS +#endif // DEFINETOKENS + +// Macro snippet that loads all the attributes from tokens +#define GENERATED_TOKEN_LOADER(endpoint) \ + do \ + { \ + } while (false) + +// Macro snippet that saves the attribute to token +#define GENERATED_TOKEN_SAVER \ + do \ + { \ + } while (false)