From a607daacfcc2742be97b887bc2b56c064a7b8916 Mon Sep 17 00:00:00 2001 From: Wang Qixiang <43193572+wqx6@users.noreply.github.com> Date: Thu, 2 Nov 2023 13:03:30 +0800 Subject: [PATCH 1/8] ESP32: Use GetPartitionLabelByNamespace in ESP32Config::ConfigValueExists() (#30143) --- src/platform/ESP32/ESP32Config.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/platform/ESP32/ESP32Config.cpp b/src/platform/ESP32/ESP32Config.cpp index 37bfe68d7e0d56..04e02f63004207 100644 --- a/src/platform/ESP32/ESP32Config.cpp +++ b/src/platform/ESP32/ESP32Config.cpp @@ -370,10 +370,10 @@ bool ESP32Config::ConfigValueExists(Key key) { #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0) nvs_iterator_t iterator = NULL; - esp_err_t err = nvs_entry_find(NVS_DEFAULT_PART_NAME, key.Namespace, NVS_TYPE_ANY, &iterator); + esp_err_t err = nvs_entry_find(GetPartitionLabelByNamespace(key.Namespace), key.Namespace, NVS_TYPE_ANY, &iterator); for (; iterator && err == ESP_OK; err = nvs_entry_next(&iterator)) #else - nvs_iterator_t iterator = nvs_entry_find(NVS_DEFAULT_PART_NAME, key.Namespace, NVS_TYPE_ANY); + nvs_iterator_t iterator = nvs_entry_find(GetPartitionLabelByNamespace(key.Namespace), key.Namespace, NVS_TYPE_ANY); for (; iterator; iterator = nvs_entry_next(iterator)) #endif { From 37f099e8d8cd52ca035d643a36c5c52a2ce0f9ee Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Thu, 2 Nov 2023 02:33:27 -0400 Subject: [PATCH 2/8] Update Darwin availability annotations. (#30165) * Mark new things as provisional. * Fix incorrect availability for ApplicationLauncher's StatusEnum introduced by https://github.com/project-chip/connectedhomeip/pull/30134 --- .../CHIP/templates/availability.yaml | 19 +++++++++++++++++-- .../CHIP/zap-generated/MTRBaseClusters.h | 8 ++++---- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/darwin/Framework/CHIP/templates/availability.yaml b/src/darwin/Framework/CHIP/templates/availability.yaml index d7b9f200956d9e..3fc8e7f616b178 100644 --- a/src/darwin/Framework/CHIP/templates/availability.yaml +++ b/src/darwin/Framework/CHIP/templates/availability.yaml @@ -3258,7 +3258,10 @@ AudioOutput: - OutputTypeEnum ApplicationLauncher: - - ApplicationLauncherStatusEnum + # StatusEnum was originally named ApplicationLauncherStatusEnum, but we + # generate the same API for the names with/without the cluster name at the + # beginning, so the name can just change here. + - StatusEnum ApplicationBasic: - ApplicationStatusEnum TestCluster: @@ -4137,7 +4140,10 @@ - Internal - Other ApplicationLauncher: - ApplicationLauncherStatusEnum: + # StatusEnum was originally named ApplicationLauncherStatusEnum, but we + # generate the same API for the names with/without the cluster name at the + # beginning, so the name can just change here. + StatusEnum: - Success - AppNotAvailable - SystemBusy @@ -7762,6 +7768,10 @@ Feature: - WaterMarks provisional: + clusters: + # Targeting Spring 2024 Matter release + - MicrowaveOvenControl + - MicrowaveOvenMode attributes: NetworkCommissioning: # Targeting Spring 2024 Matter release @@ -7777,6 +7787,11 @@ NetworkCommissioning: # Targeting Spring 2024 Matter release - ThreadCapabilitiesBitmap + bitmap values: + OnOff: + Feature: + # Targeting Spring 2024 Matter release + - OffOnly renames: bitmaps: Scenes: diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h index 6c03114a8f0dad..3a8d94a8b82028 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h @@ -16173,10 +16173,10 @@ typedef NS_OPTIONS(uint32_t, MTRAudioOutputFeature) { } MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); typedef NS_ENUM(uint8_t, MTRApplicationLauncherStatus) { - MTRApplicationLauncherStatusSuccess MTR_PROVISIONALLY_AVAILABLE = 0x00, - MTRApplicationLauncherStatusAppNotAvailable MTR_PROVISIONALLY_AVAILABLE = 0x01, - MTRApplicationLauncherStatusSystemBusy MTR_PROVISIONALLY_AVAILABLE = 0x02, -} MTR_PROVISIONALLY_AVAILABLE; + MTRApplicationLauncherStatusSuccess MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) = 0x00, + MTRApplicationLauncherStatusAppNotAvailable MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) = 0x01, + MTRApplicationLauncherStatusSystemBusy MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) = 0x02, +} MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); typedef NS_OPTIONS(uint32_t, MTRApplicationLauncherFeature) { MTRApplicationLauncherFeatureApplicationPlatform MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) = 0x1, From bfc8c327826adfbdfe520fe207f5e4d203462887 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Thu, 2 Nov 2023 04:07:06 -0400 Subject: [PATCH 3/8] Fix darwin-tests workflow file syntax. (#30162) There were extra curly braces that failed on some (but not all?) CI runs. --- .github/workflows/darwin-tests.yaml | 4 ++-- src/app/tests/suites/certification/Test_TC_APBSC_9_1.yaml | 2 +- .../darwin-framework-tool/zap-generated/test/Commands.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/darwin-tests.yaml b/.github/workflows/darwin-tests.yaml index 21f2a227be1a72..7afef91f345f4d 100644 --- a/.github/workflows/darwin-tests.yaml +++ b/.github/workflows/darwin-tests.yaml @@ -147,8 +147,8 @@ jobs: uses: actions/upload-artifact@v3 if: ${{ failure() && !env.ACT }} with: - name: framework-build-log-darwin-${{BUILD_VARIANT_FRAMEWORK_TOOL}} - path: out/darwin-x64-darwin-framework-tool-${{BUILD_VARIANT_FRAMEWORK_TOOL}}/darwin_framework_build.log + name: framework-build-log-darwin-${BUILD_VARIANT_FRAMEWORK_TOOL} + path: out/darwin-x64-darwin-framework-tool-${BUILD_VARIANT_FRAMEWORK_TOOL}/darwin_framework_build.log - name: Uploading objdir for debugging uses: actions/upload-artifact@v3 if: ${{ failure() && !env.ACT }} diff --git a/src/app/tests/suites/certification/Test_TC_APBSC_9_1.yaml b/src/app/tests/suites/certification/Test_TC_APBSC_9_1.yaml index 3809e72bc7205e..b170eb0aec2e02 100644 --- a/src/app/tests/suites/certification/Test_TC_APBSC_9_1.yaml +++ b/src/app/tests/suites/certification/Test_TC_APBSC_9_1.yaml @@ -54,7 +54,7 @@ tests: attribute: "ApplicationName" response: constraints: - type: char_string + type: long_char_string maxLength: 256 - label: "Step 4: Reads the ProductID attribute" diff --git a/zzz_generated/darwin-framework-tool/zap-generated/test/Commands.h b/zzz_generated/darwin-framework-tool/zap-generated/test/Commands.h index 84986519fb6250..1bb19ddf8d4d96 100644 --- a/zzz_generated/darwin-framework-tool/zap-generated/test/Commands.h +++ b/zzz_generated/darwin-framework-tool/zap-generated/test/Commands.h @@ -75137,7 +75137,7 @@ class Test_TC_APBSC_9_1 : public TestCommandBridge { VerifyOrReturn(CheckValue("status", err ? err.code : 0, 0)); - VerifyOrReturn(CheckConstraintType("applicationName", "long_char_string", "char_string")); + VerifyOrReturn(CheckConstraintType("applicationName", "long_char_string", "long_char_string")); VerifyOrReturn(CheckConstraintMaxLength("applicationName", value, 256)); NextTest(); }]; From bba25c50a574ec78ffd2fa51b9906752da50fc37 Mon Sep 17 00:00:00 2001 From: Karsten Sperling <113487422+ksperling-apple@users.noreply.github.com> Date: Fri, 3 Nov 2023 02:07:33 +1300 Subject: [PATCH 4/8] Small ChipCert refactoring in preparation for more work on PDC (#30163) * TLVReader: Factor Expect() helper out of Next(...) * ChipCert: Make issuerKeypair parameters const * ChipCert: Factor out EncodeExtKeyUsageExtension helper ... and tidy up the API of some other helpers a little to make them easier to re-use. * Fix doc comments as per review * Condense a few more checks into an Expect() --- .../ExampleOperationalCredentialsIssuer.cpp | 3 +- .../AndroidOperationalCredentialsIssuer.cpp | 6 +- src/credentials/CHIPCert.h | 6 +- src/credentials/CHIPCertToX509.cpp | 27 ++--- src/credentials/GenerateChipX509Cert.cpp | 98 +++++++++---------- .../CHIP/MTROperationalCredentialsDelegate.mm | 3 +- src/lib/core/OTAImageHeader.cpp | 2 +- src/lib/core/TLVReader.cpp | 27 +++-- src/lib/core/TLVReader.h | 52 +++++----- 9 files changed, 99 insertions(+), 125 deletions(-) diff --git a/src/controller/ExampleOperationalCredentialsIssuer.cpp b/src/controller/ExampleOperationalCredentialsIssuer.cpp index 132f111a18c3e0..09a9a5a99bc9bb 100644 --- a/src/controller/ExampleOperationalCredentialsIssuer.cpp +++ b/src/controller/ExampleOperationalCredentialsIssuer.cpp @@ -348,8 +348,7 @@ CHIP_ERROR ExampleOperationalCredentialsIssuer::GenerateNOCChain(const ByteSpan ReturnErrorOnFailure(reader.Next()); } - VerifyOrReturnError(reader.GetType() == kTLVType_Structure, CHIP_ERROR_WRONG_TLV_TYPE); - VerifyOrReturnError(reader.GetTag() == AnonymousTag(), CHIP_ERROR_UNEXPECTED_TLV_ELEMENT); + ReturnErrorOnFailure(reader.Expect(kTLVType_Structure, AnonymousTag())); TLVType containerType; ReturnErrorOnFailure(reader.EnterContainer(containerType)); diff --git a/src/controller/java/AndroidOperationalCredentialsIssuer.cpp b/src/controller/java/AndroidOperationalCredentialsIssuer.cpp index 063ba5dfb6cdc3..1cfa9d28d25960 100644 --- a/src/controller/java/AndroidOperationalCredentialsIssuer.cpp +++ b/src/controller/java/AndroidOperationalCredentialsIssuer.cpp @@ -186,8 +186,7 @@ CHIP_ERROR AndroidOperationalCredentialsIssuer::CallbackGenerateNOCChain(const B ReturnErrorOnFailure(reader.Next()); } - VerifyOrReturnError(reader.GetType() == kTLVType_Structure, CHIP_ERROR_WRONG_TLV_TYPE); - VerifyOrReturnError(reader.GetTag() == AnonymousTag(), CHIP_ERROR_UNEXPECTED_TLV_ELEMENT); + ReturnErrorOnFailure(reader.Expect(kTLVType_Structure, AnonymousTag())); TLVType containerType; ReturnErrorOnFailure(reader.EnterContainer(containerType)); @@ -335,8 +334,7 @@ CHIP_ERROR AndroidOperationalCredentialsIssuer::LocalGenerateNOCChain(const Byte ReturnErrorOnFailure(reader.Next()); } - VerifyOrReturnError(reader.GetType() == kTLVType_Structure, CHIP_ERROR_WRONG_TLV_TYPE); - VerifyOrReturnError(reader.GetTag() == AnonymousTag(), CHIP_ERROR_UNEXPECTED_TLV_ELEMENT); + ReturnErrorOnFailure(reader.Expect(kTLVType_Structure, AnonymousTag())); TLVType containerType; ReturnErrorOnFailure(reader.EnterContainer(containerType)); diff --git a/src/credentials/CHIPCert.h b/src/credentials/CHIPCert.h index 0f8ba1df4b2955..af2c5c1916de4b 100644 --- a/src/credentials/CHIPCert.h +++ b/src/credentials/CHIPCert.h @@ -569,7 +569,7 @@ struct X509CertRequestParams * * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise **/ -CHIP_ERROR NewRootX509Cert(const X509CertRequestParams & requestParams, Crypto::P256Keypair & issuerKeypair, +CHIP_ERROR NewRootX509Cert(const X509CertRequestParams & requestParams, const Crypto::P256Keypair & issuerKeypair, MutableByteSpan & x509Cert); /** @@ -583,7 +583,7 @@ CHIP_ERROR NewRootX509Cert(const X509CertRequestParams & requestParams, Crypto:: * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise **/ CHIP_ERROR NewICAX509Cert(const X509CertRequestParams & requestParams, const Crypto::P256PublicKey & subjectPubkey, - Crypto::P256Keypair & issuerKeypair, MutableByteSpan & x509Cert); + const Crypto::P256Keypair & issuerKeypair, MutableByteSpan & x509Cert); /** * @brief Generate a new X.509 DER encoded Node operational certificate @@ -596,7 +596,7 @@ CHIP_ERROR NewICAX509Cert(const X509CertRequestParams & requestParams, const Cry * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise **/ CHIP_ERROR NewNodeOperationalX509Cert(const X509CertRequestParams & requestParams, const Crypto::P256PublicKey & subjectPubkey, - Crypto::P256Keypair & issuerKeypair, MutableByteSpan & x509Cert); + const Crypto::P256Keypair & issuerKeypair, MutableByteSpan & x509Cert); /** * @brief diff --git a/src/credentials/CHIPCertToX509.cpp b/src/credentials/CHIPCertToX509.cpp index 47781c59d57eec..7001e51dd66faf 100644 --- a/src/credentials/CHIPCertToX509.cpp +++ b/src/credentials/CHIPCertToX509.cpp @@ -152,9 +152,7 @@ static CHIP_ERROR DecodeConvertAuthorityKeyIdentifierExtension(TLVReader & reade { // keyIdentifier [0] IMPLICIT KeyIdentifier // KeyIdentifier ::= OCTET STRING - VerifyOrReturnError(reader.GetType() == kTLVType_ByteString, CHIP_ERROR_WRONG_TLV_TYPE); - VerifyOrReturnError(reader.GetTag() == ContextTag(kTag_AuthorityKeyIdentifier), CHIP_ERROR_UNEXPECTED_TLV_ELEMENT); - + ReturnErrorOnFailure(reader.Expect(kTLVType_ByteString, ContextTag(kTag_AuthorityKeyIdentifier))); ReturnErrorOnFailure(reader.Get(certData.mAuthKeyId)); static_assert(CertificateKeyId().size() <= UINT16_MAX, "Authority key id size doesn't fit in a uint16_t"); @@ -177,9 +175,7 @@ static CHIP_ERROR DecodeConvertSubjectKeyIdentifierExtension(TLVReader & reader, // SubjectKeyIdentifier ::= KeyIdentifier // KeyIdentifier ::= OCTET STRING - VerifyOrReturnError(reader.GetType() == kTLVType_ByteString, CHIP_ERROR_WRONG_TLV_TYPE); - VerifyOrReturnError(reader.GetTag() == ContextTag(kTag_SubjectKeyIdentifier), CHIP_ERROR_UNEXPECTED_TLV_ELEMENT); - + ReturnErrorOnFailure(reader.Expect(kTLVType_ByteString, ContextTag(kTag_SubjectKeyIdentifier))); ReturnErrorOnFailure(reader.Get(certData.mSubjectKeyId)); static_assert(CertificateKeyId().size() <= UINT16_MAX, "Subject key id size doesn't fit in a uint16_t"); @@ -198,8 +194,7 @@ static CHIP_ERROR DecodeConvertKeyUsageExtension(TLVReader & reader, ASN1Writer certData.mCertFlags.Set(CertFlags::kExtPresent_KeyUsage); // KeyUsage ::= BIT STRING - VerifyOrReturnError(reader.GetTag() == ContextTag(kTag_KeyUsage), CHIP_ERROR_UNEXPECTED_TLV_ELEMENT); - + ReturnErrorOnFailure(reader.Expect(ContextTag(kTag_KeyUsage))); ReturnErrorOnFailure(reader.Get(keyUsageBits)); { @@ -229,9 +224,7 @@ static CHIP_ERROR DecodeConvertBasicConstraintsExtension(TLVReader & reader, ASN // BasicConstraints ::= SEQUENCE ASN1_START_SEQUENCE { - VerifyOrReturnError(reader.GetTag() == ContextTag(kTag_BasicConstraints), CHIP_ERROR_UNEXPECTED_TLV_ELEMENT); - VerifyOrReturnError(reader.GetType() == kTLVType_Structure, CHIP_ERROR_WRONG_TLV_TYPE); - + ReturnErrorOnFailure(reader.Expect(kTLVType_Structure, ContextTag(kTag_BasicConstraints))); ReturnErrorOnFailure(reader.EnterContainer(outerContainer)); // cA BOOLEAN DEFAULT FALSE @@ -282,9 +275,7 @@ static CHIP_ERROR DecodeConvertExtendedKeyUsageExtension(TLVReader & reader, ASN // ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId ASN1_START_SEQUENCE { - VerifyOrReturnError(reader.GetTag() == ContextTag(kTag_ExtendedKeyUsage), CHIP_ERROR_UNEXPECTED_TLV_ELEMENT); - VerifyOrReturnError(reader.GetType() == kTLVType_Array, CHIP_ERROR_WRONG_TLV_TYPE); - + ReturnErrorOnFailure(reader.Expect(kTLVType_Array, ContextTag(kTag_ExtendedKeyUsage))); ReturnErrorOnFailure(reader.EnterContainer(outerContainer)); while ((err = reader.Next(AnonymousTag())) == CHIP_NO_ERROR) @@ -312,9 +303,7 @@ static CHIP_ERROR DecodeConvertFutureExtension(TLVReader & tlvReader, ASN1Writer ByteSpan extensionSequence; ASN1Reader reader; - VerifyOrReturnError(tlvReader.GetTag() == ContextTag(kTag_FutureExtension), CHIP_ERROR_INVALID_TLV_TAG); - VerifyOrReturnError(tlvReader.GetType() == kTLVType_ByteString, CHIP_ERROR_WRONG_TLV_TYPE); - + ReturnErrorOnFailure(tlvReader.Expect(kTLVType_ByteString, ContextTag(kTag_FutureExtension))); ReturnErrorOnFailure(tlvReader.Get(extensionSequence)); reader.Init(extensionSequence); @@ -574,9 +563,7 @@ static CHIP_ERROR DecodeConvertCert(TLVReader & reader, ASN1Writer & writer, ASN { ReturnErrorOnFailure(reader.Next()); } - VerifyOrReturnError(reader.GetType() == kTLVType_Structure, CHIP_ERROR_WRONG_TLV_TYPE); - VerifyOrReturnError(reader.GetTag() == AnonymousTag(), CHIP_ERROR_UNEXPECTED_TLV_ELEMENT); - + ReturnErrorOnFailure(reader.Expect(kTLVType_Structure, AnonymousTag())); ReturnErrorOnFailure(reader.EnterContainer(containerType)); // Certificate ::= SEQUENCE diff --git a/src/credentials/GenerateChipX509Cert.cpp b/src/credentials/GenerateChipX509Cert.cpp index 86c7decf50e863..8297b85c4c5909 100644 --- a/src/credentials/GenerateChipX509Cert.cpp +++ b/src/credentials/GenerateChipX509Cert.cpp @@ -27,6 +27,7 @@ #endif #include +#include #include #include @@ -81,9 +82,7 @@ CHIP_ERROR EncodeAuthorityKeyIdentifierExtension(const Crypto::P256PublicKey & p ASN1_START_SEQUENCE { - OID extensionOID = GetOID(kOIDCategory_Extension, static_cast(kTag_AuthorityKeyIdentifier)); - - ASN1_ENCODE_OBJECT_ID(extensionOID); + ASN1_ENCODE_OBJECT_ID(kOID_Extension_AuthorityKeyIdentifier); ASN1_START_OCTET_STRING_ENCAPSULATED { @@ -111,9 +110,7 @@ CHIP_ERROR EncodeSubjectKeyIdentifierExtension(const Crypto::P256PublicKey & pub ASN1_START_SEQUENCE { - OID extensionOID = GetOID(kOIDCategory_Extension, static_cast(kTag_SubjectKeyIdentifier)); - - ASN1_ENCODE_OBJECT_ID(extensionOID); + ASN1_ENCODE_OBJECT_ID(kOID_Extension_SubjectKeyIdentifier); ASN1_START_OCTET_STRING_ENCAPSULATED { @@ -130,21 +127,46 @@ CHIP_ERROR EncodeSubjectKeyIdentifierExtension(const Crypto::P256PublicKey & pub return err; } -CHIP_ERROR EncodeKeyUsageExtension(uint16_t keyUsageBits, ASN1Writer & writer) +CHIP_ERROR EncodeExtKeyUsageExtension(std::initializer_list keyPurposeOIDs, ASN1Writer & writer) { CHIP_ERROR err = CHIP_NO_ERROR; - ASN1_START_SEQUENCE { - OID extensionOID = GetOID(kOIDCategory_Extension, static_cast(kTag_KeyUsage)); + ASN1_ENCODE_OBJECT_ID(kOID_Extension_ExtendedKeyUsage); + + // ExtKeyUsage extension MUST be marked as critical. + ASN1_ENCODE_BOOLEAN(true); + ASN1_START_OCTET_STRING_ENCAPSULATED + { + ASN1_START_SEQUENCE + { + for (auto && oid : keyPurposeOIDs) + { + ASN1_ENCODE_OBJECT_ID(oid); + } + } + ASN1_END_SEQUENCE; + } + ASN1_END_ENCAPSULATED; + } + ASN1_END_SEQUENCE; + +exit: + return err; +} - ASN1_ENCODE_OBJECT_ID(extensionOID); +CHIP_ERROR EncodeKeyUsageExtension(BitFlags keyUsageFlags, ASN1Writer & writer) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + ASN1_START_SEQUENCE + { + ASN1_ENCODE_OBJECT_ID(kOID_Extension_KeyUsage); // KeyUsage extension MUST be marked as critical. ASN1_ENCODE_BOOLEAN(true); ASN1_START_OCTET_STRING_ENCAPSULATED { - ASN1_ENCODE_BIT_STRING(keyUsageBits); + ASN1_ENCODE_BIT_STRING(keyUsageFlags.Raw()); } ASN1_END_ENCAPSULATED; } @@ -157,12 +179,9 @@ CHIP_ERROR EncodeKeyUsageExtension(uint16_t keyUsageBits, ASN1Writer & writer) CHIP_ERROR EncodeIsCAExtension(IsCACert isCA, ASN1Writer & writer) { CHIP_ERROR err = CHIP_NO_ERROR; - ASN1_START_SEQUENCE { - OID extensionOID = GetOID(kOIDCategory_Extension, static_cast(kTag_BasicConstraints)); - - ASN1_ENCODE_OBJECT_ID(extensionOID); + ASN1_ENCODE_OBJECT_ID(kOID_Extension_BasicConstraints); // BasicConstraints extension MUST be marked as critical. ASN1_ENCODE_BOOLEAN(true); @@ -191,46 +210,17 @@ CHIP_ERROR EncodeIsCAExtension(IsCACert isCA, ASN1Writer & writer) CHIP_ERROR EncodeCASpecificExtensions(ASN1Writer & writer) { ReturnErrorOnFailure(EncodeIsCAExtension(kCACert, writer)); - - uint16_t keyUsageBits = static_cast(KeyUsageFlags::kKeyCertSign) | static_cast(KeyUsageFlags::kCRLSign); - - ReturnErrorOnFailure(EncodeKeyUsageExtension(keyUsageBits, writer)); - + ReturnErrorOnFailure( + EncodeKeyUsageExtension(BitFlags(KeyUsageFlags::kKeyCertSign, KeyUsageFlags::kCRLSign), writer)); return CHIP_NO_ERROR; } CHIP_ERROR EncodeNOCSpecificExtensions(ASN1Writer & writer) { - CHIP_ERROR err = CHIP_NO_ERROR; - - uint16_t keyUsageBits = static_cast(KeyUsageFlags::kDigitalSignature); - ReturnErrorOnFailure(EncodeIsCAExtension(kNotCACert, writer)); - ReturnErrorOnFailure(EncodeKeyUsageExtension(keyUsageBits, writer)); - - ASN1_START_SEQUENCE - { - OID extensionOID = GetOID(kOIDCategory_Extension, static_cast(kTag_ExtendedKeyUsage)); - - ASN1_ENCODE_OBJECT_ID(extensionOID); - - // ExtKeyUsage extension MUST be marked as critical. - ASN1_ENCODE_BOOLEAN(true); - ASN1_START_OCTET_STRING_ENCAPSULATED - { - ASN1_START_SEQUENCE - { - ASN1_ENCODE_OBJECT_ID(kOID_KeyPurpose_ClientAuth); - ASN1_ENCODE_OBJECT_ID(kOID_KeyPurpose_ServerAuth); - } - ASN1_END_SEQUENCE; - } - ASN1_END_ENCAPSULATED; - } - ASN1_END_SEQUENCE; - -exit: - return err; + ReturnErrorOnFailure(EncodeKeyUsageExtension(KeyUsageFlags::kDigitalSignature, writer)); + ReturnErrorOnFailure(EncodeExtKeyUsageExtension({ kOID_KeyPurpose_ClientAuth, kOID_KeyPurpose_ServerAuth }, writer)); + return CHIP_NO_ERROR; } CHIP_ERROR EncodeFutureExtension(const Optional & futureExt, ASN1Writer & writer) @@ -378,7 +368,7 @@ CHIP_ERROR EncodeTBSCert(const X509CertRequestParams & requestParams, const Cryp } CHIP_ERROR NewChipX509Cert(const X509CertRequestParams & requestParams, const Crypto::P256PublicKey & subjectPubkey, - Crypto::P256Keypair & issuerKeypair, MutableByteSpan & x509Cert) + const Crypto::P256Keypair & issuerKeypair, MutableByteSpan & x509Cert) { CHIP_ERROR err = CHIP_NO_ERROR; ASN1Writer writer; @@ -411,7 +401,7 @@ CHIP_ERROR NewChipX509Cert(const X509CertRequestParams & requestParams, const Cr return err; } -DLL_EXPORT CHIP_ERROR NewRootX509Cert(const X509CertRequestParams & requestParams, Crypto::P256Keypair & issuerKeypair, +DLL_EXPORT CHIP_ERROR NewRootX509Cert(const X509CertRequestParams & requestParams, const Crypto::P256Keypair & issuerKeypair, MutableByteSpan & x509Cert) { CertType certType; @@ -424,7 +414,7 @@ DLL_EXPORT CHIP_ERROR NewRootX509Cert(const X509CertRequestParams & requestParam } DLL_EXPORT CHIP_ERROR NewICAX509Cert(const X509CertRequestParams & requestParams, const Crypto::P256PublicKey & subjectPubkey, - Crypto::P256Keypair & issuerKeypair, MutableByteSpan & x509Cert) + const Crypto::P256Keypair & issuerKeypair, MutableByteSpan & x509Cert) { CertType certType; @@ -438,8 +428,8 @@ DLL_EXPORT CHIP_ERROR NewICAX509Cert(const X509CertRequestParams & requestParams } DLL_EXPORT CHIP_ERROR NewNodeOperationalX509Cert(const X509CertRequestParams & requestParams, - const Crypto::P256PublicKey & subjectPubkey, Crypto::P256Keypair & issuerKeypair, - MutableByteSpan & x509Cert) + const Crypto::P256PublicKey & subjectPubkey, + const Crypto::P256Keypair & issuerKeypair, MutableByteSpan & x509Cert) { CertType certType; diff --git a/src/darwin/Framework/CHIP/MTROperationalCredentialsDelegate.mm b/src/darwin/Framework/CHIP/MTROperationalCredentialsDelegate.mm index 71ee2e6c198f50..888e3ddba38bfc 100644 --- a/src/darwin/Framework/CHIP/MTROperationalCredentialsDelegate.mm +++ b/src/darwin/Framework/CHIP/MTROperationalCredentialsDelegate.mm @@ -273,8 +273,7 @@ ReturnErrorOnFailure(reader.Next()); } - VerifyOrReturnError(reader.GetType() == kTLVType_Structure, CHIP_ERROR_WRONG_TLV_TYPE); - VerifyOrReturnError(reader.GetTag() == AnonymousTag(), CHIP_ERROR_UNEXPECTED_TLV_ELEMENT); + ReturnErrorOnFailure(reader.Expect(kTLVType_Structure, AnonymousTag())); TLVType containerType; ReturnErrorOnFailure(reader.EnterContainer(containerType)); diff --git a/src/lib/core/OTAImageHeader.cpp b/src/lib/core/OTAImageHeader.cpp index ebf644fff9daf8..674c08afb31429 100644 --- a/src/lib/core/OTAImageHeader.cpp +++ b/src/lib/core/OTAImageHeader.cpp @@ -163,7 +163,7 @@ CHIP_ERROR OTAImageHeaderParser::DecodeTlv(OTAImageHeader & header) ReturnErrorOnFailure(tlvReader.Next()); } - VerifyOrReturnError(tlvReader.GetTag() == TLV::ContextTag(Tag::kImageDigestType), CHIP_ERROR_UNEXPECTED_TLV_ELEMENT); + ReturnErrorOnFailure(tlvReader.Expect(TLV::ContextTag(Tag::kImageDigestType))); ReturnErrorOnFailure(tlvReader.Get(header.mImageDigestType)); ReturnErrorOnFailure(tlvReader.Next(TLV::ContextTag(Tag::kImageDigest))); ReturnErrorOnFailure(tlvReader.Get(header.mImageDigest)); diff --git a/src/lib/core/TLVReader.cpp b/src/lib/core/TLVReader.cpp index c44d0947d87d1c..1fe3b6b4c695f0 100644 --- a/src/lib/core/TLVReader.cpp +++ b/src/lib/core/TLVReader.cpp @@ -583,23 +583,30 @@ CHIP_ERROR TLVReader::Next() return CHIP_NO_ERROR; } +CHIP_ERROR TLVReader::Expect(Tag expectedTag) +{ + VerifyOrReturnError(mElemTag == expectedTag, CHIP_ERROR_UNEXPECTED_TLV_ELEMENT); + return CHIP_NO_ERROR; +} + CHIP_ERROR TLVReader::Next(Tag expectedTag) { - CHIP_ERROR err = Next(); - if (err != CHIP_NO_ERROR) - return err; - if (mElemTag != expectedTag) - return CHIP_ERROR_UNEXPECTED_TLV_ELEMENT; + ReturnErrorOnFailure(Next()); + ReturnErrorOnFailure(Expect(expectedTag)); + return CHIP_NO_ERROR; +} + +CHIP_ERROR TLVReader::Expect(TLVType expectedType, Tag expectedTag) +{ + ReturnErrorOnFailure(Expect(expectedTag)); + VerifyOrReturnError(GetType() == expectedType, CHIP_ERROR_WRONG_TLV_TYPE); return CHIP_NO_ERROR; } CHIP_ERROR TLVReader::Next(TLVType expectedType, Tag expectedTag) { - CHIP_ERROR err = Next(expectedTag); - if (err != CHIP_NO_ERROR) - return err; - if (GetType() != expectedType) - return CHIP_ERROR_WRONG_TLV_TYPE; + ReturnErrorOnFailure(Next()); + ReturnErrorOnFailure(Expect(expectedType, expectedTag)); return CHIP_NO_ERROR; } diff --git a/src/lib/core/TLVReader.h b/src/lib/core/TLVReader.h index 0acc618bc86598..6be621e6382ce6 100644 --- a/src/lib/core/TLVReader.h +++ b/src/lib/core/TLVReader.h @@ -167,56 +167,50 @@ class DLL_EXPORT TLVReader * Advances the TLVReader object to the next TLV element to be read, asserting the tag of * the new element. * - * The Next(Tag expectedTag) method is a convenience method that has the - * same behavior as Next(), but also verifies that the tag of the new TLV element matches - * the supplied argument. + * This is a convenience method that combines the behavior of Next() and Expect(). * - * @param[in] expectedTag The expected tag for the next element. + * @retval #CHIP_NO_ERROR If the reader was successfully positioned on a new element + * matching the expected parameters. + * @retval other See return values of Next() and Expect(). + */ + CHIP_ERROR Next(Tag expectedTag); + + /** + * Checks that the TLV reader is positioned at an element with the expected tag. * - * @retval #CHIP_NO_ERROR If the reader was successfully positioned on a new element. - * @retval #CHIP_END_OF_TLV If no further elements are available. + * @retval #CHIP_NO_ERROR If the reader is positioned on the expected element. * @retval #CHIP_ERROR_UNEXPECTED_TLV_ELEMENT * If the tag associated with the new element does not match the * value of the @p expectedTag argument. - * @retval #CHIP_ERROR_TLV_UNDERRUN If the underlying TLV encoding ended prematurely. - * @retval #CHIP_ERROR_INVALID_TLV_ELEMENT - * If the reader encountered an invalid or unsupported TLV - * element type. - * @retval #CHIP_ERROR_INVALID_TLV_TAG If the reader encountered a TLV tag in an invalid context. - * @retval other Other CHIP or platform error codes returned by the configured - * TLVBackingStore. - * */ - CHIP_ERROR Next(Tag expectedTag); + CHIP_ERROR Expect(Tag expectedTag); /** * Advances the TLVReader object to the next TLV element to be read, asserting the type and tag of * the new element. * - * The Next(TLVType expectedType, Tag expectedTag) method is a convenience method that has the - * same behavior as Next(), but also verifies that the type and tag of the new TLV element match - * the supplied arguments. + * This is a convenience method that combines the behavior of Next() and Expect(). + * + * @retval #CHIP_NO_ERROR If the reader was successfully positioned on a new element + * matching the expected parameters. + * @retval other See return values of Next() and Expect(). + */ + CHIP_ERROR Next(TLVType expectedType, Tag expectedTag); + + /** + * Checks that the TLV reader is positioned at an element with the expected type and tag. * * @param[in] expectedType The expected data type for the next element. * @param[in] expectedTag The expected tag for the next element. * - * @retval #CHIP_NO_ERROR If the reader was successfully positioned on a new element. - * @retval #CHIP_END_OF_TLV If no further elements are available. + * @retval #CHIP_NO_ERROR If the reader is positioned on the expected element. * @retval #CHIP_ERROR_WRONG_TLV_TYPE If the type of the new element does not match the value * of the @p expectedType argument. * @retval #CHIP_ERROR_UNEXPECTED_TLV_ELEMENT * If the tag associated with the new element does not match the * value of the @p expectedTag argument. - * @retval #CHIP_ERROR_TLV_UNDERRUN If the underlying TLV encoding ended prematurely. - * @retval #CHIP_ERROR_INVALID_TLV_ELEMENT - * If the reader encountered an invalid or unsupported TLV - * element type. - * @retval #CHIP_ERROR_INVALID_TLV_TAG If the reader encountered a TLV tag in an invalid context. - * @retval other Other CHIP or platform error codes returned by the configured - * TLVBackingStore. - * */ - CHIP_ERROR Next(TLVType expectedType, Tag expectedTag); + CHIP_ERROR Expect(TLVType expectedType, Tag expectedTag); /** * Returns the type of the current TLV element. From ea0a843c67c3415341369befd3a33c6b866296ea Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Thu, 2 Nov 2023 10:56:32 -0400 Subject: [PATCH 5/8] Make `Diagnostics Wifi Cluster` match the spec (#30154) * Fix name s/AssiciationFailure/AssociationFailureCause * zap regen * minor change to kick CI * Fix Darwin availability annotations. --------- Co-authored-by: Boris Zbarsky --- .../air-quality-sensor-app.matter | 2 +- .../all-clusters-app.matter | 2 +- .../all-clusters-minimal-app.matter | 2 +- .../bridge-app/bridge-common/bridge-app.matter | 2 +- ...ip_rootnode_dimmablelight_bCwGYSDpoe.matter | 2 +- .../rootnode_dishwasher_cc105034fe.matter | 2 +- .../rootnode_laundrywasher_fb10d238c8.matter | 2 +- ...peraturecontrolledcabinet_ffdb696680.matter | 2 +- .../contact-sensor-app.matter | 2 +- .../dishwasher-common/dishwasher-app.matter | 2 +- .../light-switch-app.matter | 2 +- .../data_model/lighting-app-wifi.matter | 2 +- .../lighting-common/lighting-app.matter | 2 +- .../silabs/data_model/lighting-wifi-app.matter | 2 +- examples/lock-app/lock-common/lock-app.matter | 2 +- .../placeholder/linux/apps/app1/config.matter | 2 +- .../placeholder/linux/apps/app2/config.matter | 2 +- .../refrigerator-app.matter | 2 +- .../resource-monitoring-app.matter | 2 +- .../temperature-measurement.matter | 2 +- .../nxp/zap/thermostat_matter_wifi.matter | 2 +- .../thermostat-common/thermostat.matter | 2 +- examples/tv-app/tv-common/tv-app.matter | 2 +- .../tv-casting-common/tv-casting-app.matter | 2 +- .../virtual-device-app.matter | 2 +- examples/window-app/common/window-app.matter | 2 +- .../chip/wifi-network-diagnostics-cluster.xml | 8 ++++---- .../data_model/controller-clusters.matter | 2 +- .../devicecontroller/ChipEventStructs.java | 10 +++++----- ...iagnosticsClusterAssociationFailureEvent.kt | 13 +++++++------ .../zap-generated/CHIPEventTLVValueDecoder.cpp | 18 +++++++++--------- src/controller/python/chip/clusters/Objects.py | 4 ++-- .../Framework/CHIP/templates/availability.yaml | 12 ++++++++++++ .../zap-generated/MTREventTLVValueDecoder.mm | 4 ++-- .../CHIP/zap-generated/MTRStructsObjc.h | 4 +++- .../CHIP/zap-generated/MTRStructsObjc.mm | 15 ++++++++++++--- .../zap-generated/cluster-objects.cpp | 6 +++--- .../app-common/zap-generated/cluster-objects.h | 12 ++++++------ .../cluster/logging/DataModelLogger.cpp | 4 ++-- 39 files changed, 94 insertions(+), 70 deletions(-) diff --git a/examples/air-quality-sensor-app/air-quality-sensor-common/air-quality-sensor-app.matter b/examples/air-quality-sensor-app/air-quality-sensor-common/air-quality-sensor-app.matter index 628058bab4590e..818a58813e30fa 100644 --- a/examples/air-quality-sensor-app/air-quality-sensor-common/air-quality-sensor-app.matter +++ b/examples/air-quality-sensor-app/air-quality-sensor-common/air-quality-sensor-app.matter @@ -945,7 +945,7 @@ server cluster WiFiNetworkDiagnostics = 54 { } info event AssociationFailure = 1 { - AssociationFailureCauseEnum associationFailure = 0; + AssociationFailureCauseEnum associationFailureCause = 0; int16u status = 1; } diff --git a/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter b/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter index 4c39209ff59908..a41f669619d4b7 100644 --- a/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter +++ b/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter @@ -1924,7 +1924,7 @@ server cluster WiFiNetworkDiagnostics = 54 { } info event AssociationFailure = 1 { - AssociationFailureCauseEnum associationFailure = 0; + AssociationFailureCauseEnum associationFailureCause = 0; int16u status = 1; } diff --git a/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.matter b/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.matter index 978f6e23eda4b1..056dad04ad36c5 100644 --- a/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.matter +++ b/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.matter @@ -1689,7 +1689,7 @@ server cluster WiFiNetworkDiagnostics = 54 { } info event AssociationFailure = 1 { - AssociationFailureCauseEnum associationFailure = 0; + AssociationFailureCauseEnum associationFailureCause = 0; int16u status = 1; } diff --git a/examples/bridge-app/bridge-common/bridge-app.matter b/examples/bridge-app/bridge-common/bridge-app.matter index 90a7ece4d648a5..ddff6e9303f1d2 100644 --- a/examples/bridge-app/bridge-common/bridge-app.matter +++ b/examples/bridge-app/bridge-common/bridge-app.matter @@ -1252,7 +1252,7 @@ server cluster WiFiNetworkDiagnostics = 54 { } info event AssociationFailure = 1 { - AssociationFailureCauseEnum associationFailure = 0; + AssociationFailureCauseEnum associationFailureCause = 0; int16u status = 1; } diff --git a/examples/chef/devices/noip_rootnode_dimmablelight_bCwGYSDpoe.matter b/examples/chef/devices/noip_rootnode_dimmablelight_bCwGYSDpoe.matter index 70c46caa00c44b..7844b98bd50c8e 100644 --- a/examples/chef/devices/noip_rootnode_dimmablelight_bCwGYSDpoe.matter +++ b/examples/chef/devices/noip_rootnode_dimmablelight_bCwGYSDpoe.matter @@ -1128,7 +1128,7 @@ server cluster WiFiNetworkDiagnostics = 54 { } info event AssociationFailure = 1 { - AssociationFailureCauseEnum associationFailure = 0; + AssociationFailureCauseEnum associationFailureCause = 0; int16u status = 1; } diff --git a/examples/chef/devices/rootnode_dishwasher_cc105034fe.matter b/examples/chef/devices/rootnode_dishwasher_cc105034fe.matter index 45c904f19f693a..ba44280e0ce4e2 100644 --- a/examples/chef/devices/rootnode_dishwasher_cc105034fe.matter +++ b/examples/chef/devices/rootnode_dishwasher_cc105034fe.matter @@ -683,7 +683,7 @@ server cluster WiFiNetworkDiagnostics = 54 { } info event AssociationFailure = 1 { - AssociationFailureCauseEnum associationFailure = 0; + AssociationFailureCauseEnum associationFailureCause = 0; int16u status = 1; } diff --git a/examples/chef/devices/rootnode_laundrywasher_fb10d238c8.matter b/examples/chef/devices/rootnode_laundrywasher_fb10d238c8.matter index 9657c9b28e6909..bf97be26bacdbf 100644 --- a/examples/chef/devices/rootnode_laundrywasher_fb10d238c8.matter +++ b/examples/chef/devices/rootnode_laundrywasher_fb10d238c8.matter @@ -683,7 +683,7 @@ server cluster WiFiNetworkDiagnostics = 54 { } info event AssociationFailure = 1 { - AssociationFailureCauseEnum associationFailure = 0; + AssociationFailureCauseEnum associationFailureCause = 0; int16u status = 1; } diff --git a/examples/chef/devices/rootnode_refrigerator_temperaturecontrolledcabinet_temperaturecontrolledcabinet_ffdb696680.matter b/examples/chef/devices/rootnode_refrigerator_temperaturecontrolledcabinet_temperaturecontrolledcabinet_ffdb696680.matter index 789ab736372331..7ba55dcba60a5d 100644 --- a/examples/chef/devices/rootnode_refrigerator_temperaturecontrolledcabinet_temperaturecontrolledcabinet_ffdb696680.matter +++ b/examples/chef/devices/rootnode_refrigerator_temperaturecontrolledcabinet_temperaturecontrolledcabinet_ffdb696680.matter @@ -683,7 +683,7 @@ server cluster WiFiNetworkDiagnostics = 54 { } info event AssociationFailure = 1 { - AssociationFailureCauseEnum associationFailure = 0; + AssociationFailureCauseEnum associationFailureCause = 0; int16u status = 1; } 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 index 847c827d4fe086..129b2a0cb4e56d 100644 --- a/examples/contact-sensor-app/contact-sensor-common/contact-sensor-app.matter +++ b/examples/contact-sensor-app/contact-sensor-common/contact-sensor-app.matter @@ -1112,7 +1112,7 @@ server cluster WiFiNetworkDiagnostics = 54 { } info event AssociationFailure = 1 { - AssociationFailureCauseEnum associationFailure = 0; + AssociationFailureCauseEnum associationFailureCause = 0; int16u status = 1; } diff --git a/examples/dishwasher-app/dishwasher-common/dishwasher-app.matter b/examples/dishwasher-app/dishwasher-common/dishwasher-app.matter index fa10fd83dd7c77..9c5faeb6cf4dc5 100644 --- a/examples/dishwasher-app/dishwasher-common/dishwasher-app.matter +++ b/examples/dishwasher-app/dishwasher-common/dishwasher-app.matter @@ -771,7 +771,7 @@ server cluster WiFiNetworkDiagnostics = 54 { } info event AssociationFailure = 1 { - AssociationFailureCauseEnum associationFailure = 0; + AssociationFailureCauseEnum associationFailureCause = 0; int16u status = 1; } diff --git a/examples/light-switch-app/light-switch-common/light-switch-app.matter b/examples/light-switch-app/light-switch-common/light-switch-app.matter index 94c3ed01bae52e..6cf23875348e2d 100644 --- a/examples/light-switch-app/light-switch-common/light-switch-app.matter +++ b/examples/light-switch-app/light-switch-common/light-switch-app.matter @@ -1431,7 +1431,7 @@ server cluster WiFiNetworkDiagnostics = 54 { } info event AssociationFailure = 1 { - AssociationFailureCauseEnum associationFailure = 0; + AssociationFailureCauseEnum associationFailureCause = 0; int16u status = 1; } diff --git a/examples/lighting-app/bouffalolab/data_model/lighting-app-wifi.matter b/examples/lighting-app/bouffalolab/data_model/lighting-app-wifi.matter index d5da4339c87488..ba3870c031a2fe 100644 --- a/examples/lighting-app/bouffalolab/data_model/lighting-app-wifi.matter +++ b/examples/lighting-app/bouffalolab/data_model/lighting-app-wifi.matter @@ -1120,7 +1120,7 @@ server cluster WiFiNetworkDiagnostics = 54 { } info event AssociationFailure = 1 { - AssociationFailureCauseEnum associationFailure = 0; + AssociationFailureCauseEnum associationFailureCause = 0; int16u status = 1; } diff --git a/examples/lighting-app/lighting-common/lighting-app.matter b/examples/lighting-app/lighting-common/lighting-app.matter index 3efe9e703cbbf4..48e3e1cd247aeb 100644 --- a/examples/lighting-app/lighting-common/lighting-app.matter +++ b/examples/lighting-app/lighting-common/lighting-app.matter @@ -1435,7 +1435,7 @@ server cluster WiFiNetworkDiagnostics = 54 { } info event AssociationFailure = 1 { - AssociationFailureCauseEnum associationFailure = 0; + AssociationFailureCauseEnum associationFailureCause = 0; int16u status = 1; } diff --git a/examples/lighting-app/silabs/data_model/lighting-wifi-app.matter b/examples/lighting-app/silabs/data_model/lighting-wifi-app.matter index db45774fc5ecb1..70013fb00ae308 100644 --- a/examples/lighting-app/silabs/data_model/lighting-wifi-app.matter +++ b/examples/lighting-app/silabs/data_model/lighting-wifi-app.matter @@ -1508,7 +1508,7 @@ server cluster WiFiNetworkDiagnostics = 54 { } info event AssociationFailure = 1 { - AssociationFailureCauseEnum associationFailure = 0; + AssociationFailureCauseEnum associationFailureCause = 0; int16u status = 1; } diff --git a/examples/lock-app/lock-common/lock-app.matter b/examples/lock-app/lock-common/lock-app.matter index 351c752274d1d4..2034741e35de47 100644 --- a/examples/lock-app/lock-common/lock-app.matter +++ b/examples/lock-app/lock-common/lock-app.matter @@ -1350,7 +1350,7 @@ server cluster WiFiNetworkDiagnostics = 54 { } info event AssociationFailure = 1 { - AssociationFailureCauseEnum associationFailure = 0; + AssociationFailureCauseEnum associationFailureCause = 0; int16u status = 1; } diff --git a/examples/placeholder/linux/apps/app1/config.matter b/examples/placeholder/linux/apps/app1/config.matter index 40f03656fa7c7d..070ceccfa6fcf5 100644 --- a/examples/placeholder/linux/apps/app1/config.matter +++ b/examples/placeholder/linux/apps/app1/config.matter @@ -2102,7 +2102,7 @@ server cluster WiFiNetworkDiagnostics = 54 { } info event AssociationFailure = 1 { - AssociationFailureCauseEnum associationFailure = 0; + AssociationFailureCauseEnum associationFailureCause = 0; int16u status = 1; } diff --git a/examples/placeholder/linux/apps/app2/config.matter b/examples/placeholder/linux/apps/app2/config.matter index 26b52eacbdfc9d..ed1762e86f50ff 100644 --- a/examples/placeholder/linux/apps/app2/config.matter +++ b/examples/placeholder/linux/apps/app2/config.matter @@ -2061,7 +2061,7 @@ server cluster WiFiNetworkDiagnostics = 54 { } info event AssociationFailure = 1 { - AssociationFailureCauseEnum associationFailure = 0; + AssociationFailureCauseEnum associationFailureCause = 0; int16u status = 1; } diff --git a/examples/refrigerator-app/refrigerator-common/refrigerator-app.matter b/examples/refrigerator-app/refrigerator-common/refrigerator-app.matter index dbbe4fc7142fdc..3b50a40083a235 100644 --- a/examples/refrigerator-app/refrigerator-common/refrigerator-app.matter +++ b/examples/refrigerator-app/refrigerator-common/refrigerator-app.matter @@ -638,7 +638,7 @@ server cluster WiFiNetworkDiagnostics = 54 { } info event AssociationFailure = 1 { - AssociationFailureCauseEnum associationFailure = 0; + AssociationFailureCauseEnum associationFailureCause = 0; int16u status = 1; } diff --git a/examples/resource-monitoring-app/resource-monitoring-common/resource-monitoring-app.matter b/examples/resource-monitoring-app/resource-monitoring-common/resource-monitoring-app.matter index 4bf471ffc11107..d382f8a8ec1b75 100644 --- a/examples/resource-monitoring-app/resource-monitoring-common/resource-monitoring-app.matter +++ b/examples/resource-monitoring-app/resource-monitoring-common/resource-monitoring-app.matter @@ -1112,7 +1112,7 @@ server cluster WiFiNetworkDiagnostics = 54 { } info event AssociationFailure = 1 { - AssociationFailureCauseEnum associationFailure = 0; + AssociationFailureCauseEnum associationFailureCause = 0; int16u status = 1; } diff --git a/examples/temperature-measurement-app/temperature-measurement-common/temperature-measurement.matter b/examples/temperature-measurement-app/temperature-measurement-common/temperature-measurement.matter index 2f492c5c2b031d..4154b7f835d005 100644 --- a/examples/temperature-measurement-app/temperature-measurement-common/temperature-measurement.matter +++ b/examples/temperature-measurement-app/temperature-measurement-common/temperature-measurement.matter @@ -698,7 +698,7 @@ server cluster WiFiNetworkDiagnostics = 54 { } info event AssociationFailure = 1 { - AssociationFailureCauseEnum associationFailure = 0; + AssociationFailureCauseEnum associationFailureCause = 0; int16u status = 1; } diff --git a/examples/thermostat/nxp/zap/thermostat_matter_wifi.matter b/examples/thermostat/nxp/zap/thermostat_matter_wifi.matter index d58570d607ab75..40ca12db738375 100644 --- a/examples/thermostat/nxp/zap/thermostat_matter_wifi.matter +++ b/examples/thermostat/nxp/zap/thermostat_matter_wifi.matter @@ -1320,7 +1320,7 @@ server cluster WiFiNetworkDiagnostics = 54 { } info event AssociationFailure = 1 { - AssociationFailureCauseEnum associationFailure = 0; + AssociationFailureCauseEnum associationFailureCause = 0; int16u status = 1; } diff --git a/examples/thermostat/thermostat-common/thermostat.matter b/examples/thermostat/thermostat-common/thermostat.matter index d5ed36f49349b8..7a80f725caf459 100644 --- a/examples/thermostat/thermostat-common/thermostat.matter +++ b/examples/thermostat/thermostat-common/thermostat.matter @@ -1201,7 +1201,7 @@ server cluster WiFiNetworkDiagnostics = 54 { } info event AssociationFailure = 1 { - AssociationFailureCauseEnum associationFailure = 0; + AssociationFailureCauseEnum associationFailureCause = 0; int16u status = 1; } diff --git a/examples/tv-app/tv-common/tv-app.matter b/examples/tv-app/tv-common/tv-app.matter index 02db5c30952677..e252b1124a4653 100644 --- a/examples/tv-app/tv-common/tv-app.matter +++ b/examples/tv-app/tv-common/tv-app.matter @@ -1355,7 +1355,7 @@ server cluster WiFiNetworkDiagnostics = 54 { } info event AssociationFailure = 1 { - AssociationFailureCauseEnum associationFailure = 0; + AssociationFailureCauseEnum associationFailureCause = 0; int16u status = 1; } diff --git a/examples/tv-casting-app/tv-casting-common/tv-casting-app.matter b/examples/tv-casting-app/tv-casting-common/tv-casting-app.matter index 6a70fe74cd79b8..51c888eb5c70d2 100644 --- a/examples/tv-casting-app/tv-casting-common/tv-casting-app.matter +++ b/examples/tv-casting-app/tv-casting-common/tv-casting-app.matter @@ -1035,7 +1035,7 @@ server cluster WiFiNetworkDiagnostics = 54 { } info event AssociationFailure = 1 { - AssociationFailureCauseEnum associationFailure = 0; + AssociationFailureCauseEnum associationFailureCause = 0; int16u status = 1; } diff --git a/examples/virtual-device-app/virtual-device-common/virtual-device-app.matter b/examples/virtual-device-app/virtual-device-common/virtual-device-app.matter index 34f7a65be0d733..defa6c06f900d5 100644 --- a/examples/virtual-device-app/virtual-device-common/virtual-device-app.matter +++ b/examples/virtual-device-app/virtual-device-common/virtual-device-app.matter @@ -1494,7 +1494,7 @@ server cluster WiFiNetworkDiagnostics = 54 { } info event AssociationFailure = 1 { - AssociationFailureCauseEnum associationFailure = 0; + AssociationFailureCauseEnum associationFailureCause = 0; int16u status = 1; } diff --git a/examples/window-app/common/window-app.matter b/examples/window-app/common/window-app.matter index 6b5f06125fcf6e..2101288126d301 100644 --- a/examples/window-app/common/window-app.matter +++ b/examples/window-app/common/window-app.matter @@ -1333,7 +1333,7 @@ server cluster WiFiNetworkDiagnostics = 54 { } info event AssociationFailure = 1 { - AssociationFailureCauseEnum associationFailure = 0; + AssociationFailureCauseEnum associationFailureCause = 0; int16u status = 1; } diff --git a/src/app/zap-templates/zcl/data-model/chip/wifi-network-diagnostics-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/wifi-network-diagnostics-cluster.xml index 65e177285a3978..a2d0ca758de91e 100644 --- a/src/app/zap-templates/zcl/data-model/chip/wifi-network-diagnostics-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/wifi-network-diagnostics-cluster.xml @@ -23,7 +23,7 @@ limitations under the License. - + @@ -80,12 +80,12 @@ limitations under the License. Indicate that a Node has failed to connect, or reconnect, to a Wi-Fi access point. - - + + Indicate that a Node’s connection status to a Wi-Fi network has changed. - + diff --git a/src/controller/data_model/controller-clusters.matter b/src/controller/data_model/controller-clusters.matter index b7269a4946abd9..082f769f3b945d 100644 --- a/src/controller/data_model/controller-clusters.matter +++ b/src/controller/data_model/controller-clusters.matter @@ -2052,7 +2052,7 @@ client cluster WiFiNetworkDiagnostics = 54 { } info event AssociationFailure = 1 { - AssociationFailureCauseEnum associationFailure = 0; + AssociationFailureCauseEnum associationFailureCause = 0; int16u status = 1; } diff --git a/src/controller/java/generated/java/chip/devicecontroller/ChipEventStructs.java b/src/controller/java/generated/java/chip/devicecontroller/ChipEventStructs.java index be50323f6c5b54..5c4f9a7b529dc7 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ChipEventStructs.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ChipEventStructs.java @@ -596,13 +596,13 @@ public String toString() { } } public static class WiFiNetworkDiagnosticsClusterAssociationFailureEvent { - public Integer associationFailure; + public Integer associationFailureCause; public Integer status; public WiFiNetworkDiagnosticsClusterAssociationFailureEvent( - Integer associationFailure, + Integer associationFailureCause, Integer status ) { - this.associationFailure = associationFailure; + this.associationFailureCause = associationFailureCause; this.status = status; } @@ -610,8 +610,8 @@ public WiFiNetworkDiagnosticsClusterAssociationFailureEvent( public String toString() { StringBuilder output = new StringBuilder(); output.append("WiFiNetworkDiagnosticsClusterAssociationFailureEvent {\n"); - output.append("\tassociationFailure: "); - output.append(associationFailure); + output.append("\tassociationFailureCause: "); + output.append(associationFailureCause); output.append("\n"); output.append("\tstatus: "); output.append(status); diff --git a/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/WiFiNetworkDiagnosticsClusterAssociationFailureEvent.kt b/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/WiFiNetworkDiagnosticsClusterAssociationFailureEvent.kt index 6547c9d894a71f..2f94dc8e6b1c58 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/WiFiNetworkDiagnosticsClusterAssociationFailureEvent.kt +++ b/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/WiFiNetworkDiagnosticsClusterAssociationFailureEvent.kt @@ -23,12 +23,12 @@ import matter.tlv.TlvReader import matter.tlv.TlvWriter class WiFiNetworkDiagnosticsClusterAssociationFailureEvent( - val associationFailure: UInt, + val associationFailureCause: UInt, val status: UInt ) { override fun toString(): String = buildString { append("WiFiNetworkDiagnosticsClusterAssociationFailureEvent {\n") - append("\tassociationFailure : $associationFailure\n") + append("\tassociationFailureCause : $associationFailureCause\n") append("\tstatus : $status\n") append("}\n") } @@ -36,14 +36,14 @@ class WiFiNetworkDiagnosticsClusterAssociationFailureEvent( fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { tlvWriter.apply { startStructure(tlvTag) - put(ContextSpecificTag(TAG_ASSOCIATION_FAILURE), associationFailure) + put(ContextSpecificTag(TAG_ASSOCIATION_FAILURE_CAUSE), associationFailureCause) put(ContextSpecificTag(TAG_STATUS), status) endStructure() } } companion object { - private const val TAG_ASSOCIATION_FAILURE = 0 + private const val TAG_ASSOCIATION_FAILURE_CAUSE = 0 private const val TAG_STATUS = 1 fun fromTlv( @@ -51,12 +51,13 @@ class WiFiNetworkDiagnosticsClusterAssociationFailureEvent( tlvReader: TlvReader ): WiFiNetworkDiagnosticsClusterAssociationFailureEvent { tlvReader.enterStructure(tlvTag) - val associationFailure = tlvReader.getUInt(ContextSpecificTag(TAG_ASSOCIATION_FAILURE)) + val associationFailureCause = + tlvReader.getUInt(ContextSpecificTag(TAG_ASSOCIATION_FAILURE_CAUSE)) val status = tlvReader.getUInt(ContextSpecificTag(TAG_STATUS)) tlvReader.exitContainer() - return WiFiNetworkDiagnosticsClusterAssociationFailureEvent(associationFailure, status) + return WiFiNetworkDiagnosticsClusterAssociationFailureEvent(associationFailureCause, status) } } } diff --git a/src/controller/java/zap-generated/CHIPEventTLVValueDecoder.cpp b/src/controller/java/zap-generated/CHIPEventTLVValueDecoder.cpp index 99218afe98e445..118ea6f0f73f89 100644 --- a/src/controller/java/zap-generated/CHIPEventTLVValueDecoder.cpp +++ b/src/controller/java/zap-generated/CHIPEventTLVValueDecoder.cpp @@ -1680,13 +1680,13 @@ jobject DecodeEventValue(const app::ConcreteEventPath & aPath, TLV::TLVReader & { return nullptr; } - jobject value_associationFailure; - std::string value_associationFailureClassName = "java/lang/Integer"; - std::string value_associationFailureCtorSignature = "(I)V"; - jint jnivalue_associationFailure = static_cast(cppValue.associationFailure); - chip::JniReferences::GetInstance().CreateBoxedObject(value_associationFailureClassName.c_str(), - value_associationFailureCtorSignature.c_str(), - jnivalue_associationFailure, value_associationFailure); + jobject value_associationFailureCause; + std::string value_associationFailureCauseClassName = "java/lang/Integer"; + std::string value_associationFailureCauseCtorSignature = "(I)V"; + jint jnivalue_associationFailureCause = static_cast(cppValue.associationFailureCause); + chip::JniReferences::GetInstance().CreateBoxedObject( + value_associationFailureCauseClassName.c_str(), value_associationFailureCauseCtorSignature.c_str(), + jnivalue_associationFailureCause, value_associationFailureCause); jobject value_status; std::string value_statusClassName = "java/lang/Integer"; @@ -1713,8 +1713,8 @@ jobject DecodeEventValue(const app::ConcreteEventPath & aPath, TLV::TLVReader & return nullptr; } - jobject value = - env->NewObject(associationFailureStructClass, associationFailureStructCtor, value_associationFailure, value_status); + jobject value = env->NewObject(associationFailureStructClass, associationFailureStructCtor, + value_associationFailureCause, value_status); return value; } diff --git a/src/controller/python/chip/clusters/Objects.py b/src/controller/python/chip/clusters/Objects.py index e17a0c0c65d6c7..9f61803a00a6e5 100644 --- a/src/controller/python/chip/clusters/Objects.py +++ b/src/controller/python/chip/clusters/Objects.py @@ -10879,11 +10879,11 @@ def event_id(cls) -> int: def descriptor(cls) -> ClusterObjectDescriptor: return ClusterObjectDescriptor( Fields=[ - ClusterObjectFieldDescriptor(Label="associationFailure", Tag=0, Type=WiFiNetworkDiagnostics.Enums.AssociationFailureCauseEnum), + ClusterObjectFieldDescriptor(Label="associationFailureCause", Tag=0, Type=WiFiNetworkDiagnostics.Enums.AssociationFailureCauseEnum), ClusterObjectFieldDescriptor(Label="status", Tag=1, Type=uint), ]) - associationFailure: 'WiFiNetworkDiagnostics.Enums.AssociationFailureCauseEnum' = 0 + associationFailureCause: 'WiFiNetworkDiagnostics.Enums.AssociationFailureCauseEnum' = 0 status: 'uint' = 0 @dataclass diff --git a/src/darwin/Framework/CHIP/templates/availability.yaml b/src/darwin/Framework/CHIP/templates/availability.yaml index 3fc8e7f616b178..0dc3628958845f 100644 --- a/src/darwin/Framework/CHIP/templates/availability.yaml +++ b/src/darwin/Framework/CHIP/templates/availability.yaml @@ -7735,6 +7735,10 @@ - release: "Future" versions: "future" introduced: + event fields: + WiFiNetworkDiagnostics: + AssociationFailure: + - associationFailureCause bitmaps: Scenes: - CopyModeBitmap @@ -7757,6 +7761,10 @@ Feature: - Basic deprecated: + event fields: + WiFiNetworkDiagnostics: + AssociationFailure: + - associationFailure bitmaps: Scenes: - ScenesCopyMode @@ -7793,6 +7801,10 @@ # Targeting Spring 2024 Matter release - OffOnly renames: + event fields: + WiFiNetworkDiagnostics: + AssociationFailure: + associationFailureCause: associationFailure bitmaps: Scenes: CopyModeBitmap: ScenesCopyMode diff --git a/src/darwin/Framework/CHIP/zap-generated/MTREventTLVValueDecoder.mm b/src/darwin/Framework/CHIP/zap-generated/MTREventTLVValueDecoder.mm index c4efe8fc35d173..1b857e0ab5d2e4 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTREventTLVValueDecoder.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTREventTLVValueDecoder.mm @@ -1193,8 +1193,8 @@ static id _Nullable DecodeEventPayloadForWiFiNetworkDiagnosticsCluster(EventId a do { NSNumber * _Nonnull memberValue; - memberValue = [NSNumber numberWithUnsignedChar:chip::to_underlying(cppValue.associationFailure)]; - value.associationFailure = memberValue; + memberValue = [NSNumber numberWithUnsignedChar:chip::to_underlying(cppValue.associationFailureCause)]; + value.associationFailureCause = memberValue; } while (0); do { NSNumber * _Nonnull memberValue; diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.h b/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.h index c78f885a4625e6..3c197167dacc2c 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.h @@ -545,7 +545,9 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) @interface MTRWiFiNetworkDiagnosticsClusterAssociationFailureEvent : NSObject -@property (nonatomic, copy) NSNumber * _Nonnull associationFailure MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); +@property (nonatomic, copy) NSNumber * _Nonnull associationFailureCause MTR_NEWLY_AVAILABLE; +@property (nonatomic, copy) NSNumber * _Nonnull associationFailure MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) + MTR_NEWLY_DEPRECATED("Please use associationFailureCause"); @property (nonatomic, copy) NSNumber * _Nonnull status MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); @end diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.mm b/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.mm index 3d09597722ce57..c7000fa3be2752 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.mm @@ -1848,7 +1848,7 @@ - (instancetype)init { if (self = [super init]) { - _associationFailure = @(0); + _associationFailureCause = @(0); _status = @(0); } @@ -1859,7 +1859,7 @@ - (id)copyWithZone:(NSZone * _Nullable)zone { auto other = [[MTRWiFiNetworkDiagnosticsClusterAssociationFailureEvent alloc] init]; - other.associationFailure = self.associationFailure; + other.associationFailureCause = self.associationFailureCause; other.status = self.status; return other; @@ -1867,10 +1867,19 @@ - (id)copyWithZone:(NSZone * _Nullable)zone - (NSString *)description { - NSString * descriptionString = [NSString stringWithFormat:@"<%@: associationFailure:%@; status:%@; >", NSStringFromClass([self class]), _associationFailure, _status]; + NSString * descriptionString = [NSString stringWithFormat:@"<%@: associationFailureCause:%@; status:%@; >", NSStringFromClass([self class]), _associationFailureCause, _status]; return descriptionString; } +- (void)setAssociationFailure:(NSNumber * _Nonnull)associationFailure +{ + self.associationFailureCause = associationFailure; +} + +- (NSNumber * _Nonnull)associationFailure +{ + return self.associationFailureCause; +} @end @implementation MTRWiFiNetworkDiagnosticsClusterConnectionStatusEvent diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp index d94f544f06837d..0aeb0447d75785 100644 --- a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp +++ b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp @@ -7565,7 +7565,7 @@ CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const { TLV::TLVType outer; ReturnErrorOnFailure(aWriter.StartContainer(aTag, TLV::kTLVType_Structure, outer)); - ReturnErrorOnFailure(DataModel::Encode(aWriter, TLV::ContextTag(Fields::kAssociationFailure), associationFailure)); + ReturnErrorOnFailure(DataModel::Encode(aWriter, TLV::ContextTag(Fields::kAssociationFailureCause), associationFailureCause)); ReturnErrorOnFailure(DataModel::Encode(aWriter, TLV::ContextTag(Fields::kStatus), status)); return aWriter.EndContainer(outer); } @@ -7584,9 +7584,9 @@ CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) CHIP_ERROR err = CHIP_NO_ERROR; const uint8_t __context_tag = std::get(__element); - if (__context_tag == to_underlying(Fields::kAssociationFailure)) + if (__context_tag == to_underlying(Fields::kAssociationFailureCause)) { - err = DataModel::Decode(reader, associationFailure); + err = DataModel::Decode(reader, associationFailureCause); } else if (__context_tag == to_underlying(Fields::kStatus)) { diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h index 885994ed962434..ee1815a5ed71c0 100644 --- a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h +++ b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h @@ -10304,8 +10304,8 @@ static constexpr PriorityLevel kPriorityLevel = PriorityLevel::Info; enum class Fields : uint8_t { - kAssociationFailure = 0, - kStatus = 1, + kAssociationFailureCause = 0, + kStatus = 1, }; struct Type @@ -10316,8 +10316,8 @@ struct Type static constexpr ClusterId GetClusterId() { return Clusters::WiFiNetworkDiagnostics::Id; } static constexpr bool kIsFabricScoped = false; - AssociationFailureCauseEnum associationFailure = static_cast(0); - uint16_t status = static_cast(0); + AssociationFailureCauseEnum associationFailureCause = static_cast(0); + uint16_t status = static_cast(0); CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; }; @@ -10329,8 +10329,8 @@ struct DecodableType static constexpr EventId GetEventId() { return Events::AssociationFailure::Id; } static constexpr ClusterId GetClusterId() { return Clusters::WiFiNetworkDiagnostics::Id; } - AssociationFailureCauseEnum associationFailure = static_cast(0); - uint16_t status = static_cast(0); + AssociationFailureCauseEnum associationFailureCause = static_cast(0); + uint16_t status = static_cast(0); CHIP_ERROR Decode(TLV::TLVReader & reader); }; diff --git a/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp b/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp index adc4e2611faf32..fdcf0f06a98d71 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp +++ b/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp @@ -3386,10 +3386,10 @@ CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, { DataModelLogger::LogString(label, indent, "{"); { - CHIP_ERROR err = DataModelLogger::LogValue("AssociationFailure", indent + 1, value.associationFailure); + CHIP_ERROR err = DataModelLogger::LogValue("AssociationFailureCause", indent + 1, value.associationFailureCause); if (err != CHIP_NO_ERROR) { - DataModelLogger::LogString(indent + 1, "Event truncated due to invalid value for 'AssociationFailure'"); + DataModelLogger::LogString(indent + 1, "Event truncated due to invalid value for 'AssociationFailureCause'"); return err; } } From 005ab54abf88d1d124fa3880b26c596ecf545f44 Mon Sep 17 00:00:00 2001 From: C Freeman Date: Thu, 2 Nov 2023 10:56:51 -0400 Subject: [PATCH 6/8] Change callables to instances to allow printing (#30149) * Change callables to instances to allow printing If I just write these as callable classes, I can stringify them and we can get a decent print of the expected conformance so that the error messages are more informative and I don't need to keep going back to the spec. Also added tests, and expanded the error messages in the test. * Restyled by isort --------- Co-authored-by: Restyled.io --- .../TC_DeviceBasicComposition.py | 19 +- src/python_testing/TestConformanceSupport.py | 37 ++++ src/python_testing/conformance_support.py | 187 ++++++++++++------ 3 files changed, 183 insertions(+), 60 deletions(-) diff --git a/src/python_testing/TC_DeviceBasicComposition.py b/src/python_testing/TC_DeviceBasicComposition.py index 9d9ed9e75a5285..69a6d6433cdcf5 100644 --- a/src/python_testing/TC_DeviceBasicComposition.py +++ b/src/python_testing/TC_DeviceBasicComposition.py @@ -31,6 +31,7 @@ import chip.clusters.ClusterObjects import chip.tlv from chip.clusters.Attribute import ValueDecodeFailure +from chip.tlv import uint from conformance_support import ConformanceDecision, conformance_allowed from matter_testing_support import (AttributePathLocation, ClusterPathLocation, CommandPathLocation, MatterBaseTest, async_test_body, default_matter_test_main) @@ -1004,6 +1005,14 @@ def test_DESC_2_2(self): self.fail_current_test("Problems with tags lists") def test_spec_conformance(self): + def conformance_str(conformance: Callable, feature_map: uint, feature_dict: dict[str, uint]) -> str: + codes = [] + for mask, details in feature_dict.items(): + if mask & feature_map: + codes.append(details.code) + + return f'Conformance: {str(conformance)}, implemented features: {",".join(codes)}' + success = True # TODO: provisional needs to be an input parameter allow_provisional = True @@ -1051,7 +1060,7 @@ def test_spec_conformance(self): conformance_decision = xml_feature.conformance(feature_map, attribute_list, all_command_list) if conformance_decision == ConformanceDecision.MANDATORY and feature_mask not in feature_masks: self.record_error(self.get_test_name(), location=location, - problem=f'Required feature with mask 0x{f:02x} is not present in feature map') + problem=f'Required feature with mask 0x{f:02x} is not present in feature map. {conformance_str(xml_feature.conformance, feature_map, clusters[cluster_id].features)}') success = False # Attribute conformance checking @@ -1070,14 +1079,14 @@ def test_spec_conformance(self): if not conformance_allowed(conformance_decision, allow_provisional): location = AttributePathLocation(endpoint_id=endpoint_id, cluster_id=cluster_id, attribute_id=attribute_id) self.record_error(self.get_test_name(), location=location, - problem=f'Attribute 0x{attribute_id:02x} is included, but is disallowed by conformance') + problem=f'Attribute 0x{attribute_id:02x} is included, but is disallowed by conformance. {conformance_str(xml_attribute.conformance, feature_map, clusters[cluster_id].features)}') success = False for attribute_id, xml_attribute in clusters[cluster_id].attributes.items(): conformance_decision = xml_attribute.conformance(feature_map, attribute_list, all_command_list) if conformance_decision == ConformanceDecision.MANDATORY and attribute_id not in cluster.keys(): location = AttributePathLocation(endpoint_id=endpoint_id, cluster_id=cluster_id, attribute_id=attribute_id) self.record_error(self.get_test_name(), location=location, - problem=f'Attribute 0x{attribute_id:02x} is required, but is not present on the DUT') + problem=f'Attribute 0x{attribute_id:02x} is required, but is not present on the DUT. {conformance_str(xml_attribute.conformance, feature_map, clusters[cluster_id].features)}') success = False def check_spec_conformance_for_commands(command_type: CommandType) -> bool: @@ -1101,14 +1110,14 @@ def check_spec_conformance_for_commands(command_type: CommandType) -> bool: conformance_decision = xml_command.conformance(feature_map, attribute_list, all_command_list) if not conformance_allowed(conformance_decision, allow_provisional): self.record_error(self.get_test_name(), location=location, - problem=f'Command 0x{command_id:02x} is included, but disallowed by conformance') + problem=f'Command 0x{command_id:02x} is included, but disallowed by conformance. {conformance_str(xml_command.conformance, feature_map, clusters[cluster_id].features)}') success = False for command_id, xml_command in xml_commands_dict.items(): conformance_decision = xml_command.conformance(feature_map, attribute_list, all_command_list) if conformance_decision == ConformanceDecision.MANDATORY and command_id not in command_list: location = CommandPathLocation(endpoint_id=endpoint_id, cluster_id=cluster_id, command_id=command_id) self.record_error(self.get_test_name(), location=location, - problem=f'Command 0x{command_id:02x} is required, but is not present on the DUT') + problem=f'Command 0x{command_id:02x} is required, but is not present on the DUT. {conformance_str(xml_command.conformance, feature_map, clusters[cluster_id].features)}') success = False return success diff --git a/src/python_testing/TestConformanceSupport.py b/src/python_testing/TestConformanceSupport.py index 53f9e885ff9449..788f1025a52fa3 100644 --- a/src/python_testing/TestConformanceSupport.py +++ b/src/python_testing/TestConformanceSupport.py @@ -53,6 +53,7 @@ async def test_conformance_mandatory(self): xml_callable = parse_callable_from_xml(et, self.params) for f in self.feature_maps: asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.MANDATORY) + asserts.assert_equal(str(xml_callable), 'M') @async_test_body async def test_conformance_optional(self): @@ -61,6 +62,7 @@ async def test_conformance_optional(self): xml_callable = parse_callable_from_xml(et, self.params) for f in self.feature_maps: asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.OPTIONAL) + asserts.assert_equal(str(xml_callable), 'O') @async_test_body async def test_conformance_disallowed(self): @@ -69,12 +71,14 @@ async def test_conformance_disallowed(self): xml_callable = parse_callable_from_xml(et, self.params) for f in self.feature_maps: asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.DISALLOWED) + asserts.assert_equal(str(xml_callable), 'X') xml = '' et = ElementTree.fromstring(xml) xml_callable = parse_callable_from_xml(et, self.params) for f in self.feature_maps: asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.DISALLOWED) + asserts.assert_equal(str(xml_callable), 'D') @async_test_body async def test_conformance_provisional(self): @@ -83,6 +87,7 @@ async def test_conformance_provisional(self): xml_callable = parse_callable_from_xml(et, self.params) for f in self.feature_maps: asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.PROVISIONAL) + asserts.assert_equal(str(xml_callable), 'P') @async_test_body async def test_conformance_mandatory_on_condition(self): @@ -96,6 +101,7 @@ async def test_conformance_mandatory_on_condition(self): asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.MANDATORY) else: asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.NOT_APPLICABLE) + asserts.assert_equal(str(xml_callable), 'AB') xml = ('' '' @@ -107,6 +113,7 @@ async def test_conformance_mandatory_on_condition(self): asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.MANDATORY) else: asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.NOT_APPLICABLE) + asserts.assert_equal(str(xml_callable), 'CD') # single attribute mandatory xml = ('' @@ -119,6 +126,7 @@ async def test_conformance_mandatory_on_condition(self): asserts.assert_equal(xml_callable(0x00, a, []), ConformanceDecision.MANDATORY) else: asserts.assert_equal(xml_callable(0x00, a, []), ConformanceDecision.NOT_APPLICABLE) + asserts.assert_equal(str(xml_callable), 'attr1') xml = ('' '' @@ -130,6 +138,7 @@ async def test_conformance_mandatory_on_condition(self): asserts.assert_equal(xml_callable(0x00, a, []), ConformanceDecision.MANDATORY) else: asserts.assert_equal(xml_callable(0x00, a, []), ConformanceDecision.NOT_APPLICABLE) + asserts.assert_equal(str(xml_callable), 'attr2') # test command in optional and in boolean - this is the same as attribute essentially, so testing every permutation is overkill @@ -146,6 +155,7 @@ async def test_conformance_optional_on_condition(self): asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.OPTIONAL) else: asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.NOT_APPLICABLE) + asserts.assert_equal(str(xml_callable), '[AB]') xml = ('' '' @@ -157,6 +167,7 @@ async def test_conformance_optional_on_condition(self): asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.OPTIONAL) else: asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.NOT_APPLICABLE) + asserts.assert_equal(str(xml_callable), '[CD]') # single attribute optional xml = ('' @@ -169,6 +180,7 @@ async def test_conformance_optional_on_condition(self): asserts.assert_equal(xml_callable(0x00, a, []), ConformanceDecision.OPTIONAL) else: asserts.assert_equal(xml_callable(0x00, a, []), ConformanceDecision.NOT_APPLICABLE) + asserts.assert_equal(str(xml_callable), '[attr1]') xml = ('' '' @@ -180,6 +192,7 @@ async def test_conformance_optional_on_condition(self): asserts.assert_equal(xml_callable(0x00, a, []), ConformanceDecision.OPTIONAL) else: asserts.assert_equal(xml_callable(0x00, a, []), ConformanceDecision.NOT_APPLICABLE) + asserts.assert_equal(str(xml_callable), '[attr2]') # single command optional xml = ('' @@ -192,6 +205,7 @@ async def test_conformance_optional_on_condition(self): asserts.assert_equal(xml_callable(0x00, [], c), ConformanceDecision.OPTIONAL) else: asserts.assert_equal(xml_callable(0x00, [], c), ConformanceDecision.NOT_APPLICABLE) + asserts.assert_equal(str(xml_callable), '[cmd1]') xml = ('' '' @@ -203,6 +217,7 @@ async def test_conformance_optional_on_condition(self): asserts.assert_equal(xml_callable(0x00, [], c), ConformanceDecision.OPTIONAL) else: asserts.assert_equal(xml_callable(0x00, [], c), ConformanceDecision.NOT_APPLICABLE) + asserts.assert_equal(str(xml_callable), '[cmd2]') @async_test_body async def test_conformance_not_term_mandatory(self): @@ -219,6 +234,7 @@ async def test_conformance_not_term_mandatory(self): asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.MANDATORY) else: asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.NOT_APPLICABLE) + asserts.assert_equal(str(xml_callable), '!AB') xml = ('' '' @@ -232,6 +248,7 @@ async def test_conformance_not_term_mandatory(self): asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.MANDATORY) else: asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.NOT_APPLICABLE) + asserts.assert_equal(str(xml_callable), '!CD') # single attribute not mandatory xml = ('' @@ -246,6 +263,7 @@ async def test_conformance_not_term_mandatory(self): asserts.assert_equal(xml_callable(0x00, a, []), ConformanceDecision.MANDATORY) else: asserts.assert_equal(xml_callable(0x00, a, []), ConformanceDecision.NOT_APPLICABLE) + asserts.assert_equal(str(xml_callable), '!attr1') xml = ('' '' @@ -259,6 +277,7 @@ async def test_conformance_not_term_mandatory(self): asserts.assert_equal(xml_callable(0x00, a, []), ConformanceDecision.MANDATORY) else: asserts.assert_equal(xml_callable(0x00, a, []), ConformanceDecision.NOT_APPLICABLE) + asserts.assert_equal(str(xml_callable), '!attr2') @async_test_body async def test_conformance_not_term_optional(self): @@ -275,6 +294,7 @@ async def test_conformance_not_term_optional(self): asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.OPTIONAL) else: asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.NOT_APPLICABLE) + asserts.assert_equal(str(xml_callable), '[!AB]') xml = ('' '' @@ -288,6 +308,7 @@ async def test_conformance_not_term_optional(self): asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.OPTIONAL) else: asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.NOT_APPLICABLE) + asserts.assert_equal(str(xml_callable), '[!CD]') @async_test_body async def test_conformance_and_term(self): @@ -305,6 +326,7 @@ async def test_conformance_and_term(self): asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.MANDATORY) else: asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.NOT_APPLICABLE) + asserts.assert_equal(str(xml_callable), 'AB & CD') # and term for attributes only xml = ('' @@ -320,6 +342,7 @@ async def test_conformance_and_term(self): asserts.assert_equal(xml_callable(0x00, a, []), ConformanceDecision.MANDATORY) else: asserts.assert_equal(xml_callable(0x00, a, []), ConformanceDecision.NOT_APPLICABLE) + asserts.assert_equal(str(xml_callable), 'attr1 & attr2') # and term for feature and attribute xml = ('' @@ -336,6 +359,7 @@ async def test_conformance_and_term(self): asserts.assert_equal(xml_callable(f, a, []), ConformanceDecision.MANDATORY) else: asserts.assert_equal(xml_callable(f, a, []), ConformanceDecision.NOT_APPLICABLE) + asserts.assert_equal(str(xml_callable), 'AB & attr2') @async_test_body async def test_conformance_or_term(self): @@ -353,6 +377,7 @@ async def test_conformance_or_term(self): asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.MANDATORY) else: asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.NOT_APPLICABLE) + asserts.assert_equal(str(xml_callable), 'AB | CD') # or term attribute only xml = ('' @@ -368,6 +393,7 @@ async def test_conformance_or_term(self): asserts.assert_equal(xml_callable(0x00, a, []), ConformanceDecision.MANDATORY) else: asserts.assert_equal(xml_callable(0x00, a, []), ConformanceDecision.NOT_APPLICABLE) + asserts.assert_equal(str(xml_callable), 'attr1 | attr2') # or term feature and attribute xml = ('' @@ -384,6 +410,7 @@ async def test_conformance_or_term(self): asserts.assert_equal(xml_callable(f, a, []), ConformanceDecision.MANDATORY) else: asserts.assert_equal(xml_callable(f, a, []), ConformanceDecision.NOT_APPLICABLE) + asserts.assert_equal(str(xml_callable), 'AB | attr2') @async_test_body async def test_conformance_and_term_with_not(self): @@ -403,6 +430,7 @@ async def test_conformance_and_term_with_not(self): asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.OPTIONAL) else: asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.NOT_APPLICABLE) + asserts.assert_equal(str(xml_callable), '[!AB & CD]') @async_test_body async def test_conformance_or_term_with_not(self): @@ -422,6 +450,7 @@ async def test_conformance_or_term_with_not(self): asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.MANDATORY) else: asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.NOT_APPLICABLE) + asserts.assert_equal(str(xml_callable), 'AB | !CD') # not around or term with xml = ('' @@ -439,6 +468,7 @@ async def test_conformance_or_term_with_not(self): asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.OPTIONAL) else: asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.NOT_APPLICABLE) + asserts.assert_equal(str(xml_callable), '[!(AB | CD)]') @async_test_body async def test_conformance_and_term_with_three_terms(self): @@ -459,6 +489,7 @@ async def test_conformance_and_term_with_three_terms(self): asserts.assert_equal(xml_callable(0x01, [], []), ConformanceDecision.NOT_APPLICABLE) # all features asserts.assert_equal(xml_callable(0x07, [], []), ConformanceDecision.OPTIONAL) + asserts.assert_equal(str(xml_callable), '[AB & CD & EF]') # and term with one of each xml = ('' @@ -477,6 +508,7 @@ async def test_conformance_and_term_with_three_terms(self): asserts.assert_equal(xml_callable(f, a, c), ConformanceDecision.OPTIONAL) else: asserts.assert_equal(xml_callable(f, a, c), ConformanceDecision.NOT_APPLICABLE) + asserts.assert_equal(str(xml_callable), '[AB & attr1 & cmd1]') @async_test_body async def test_conformance_or_term_with_three_terms(self): @@ -496,6 +528,7 @@ async def test_conformance_or_term_with_three_terms(self): asserts.assert_equal(xml_callable(0x01, [], []), ConformanceDecision.OPTIONAL) # all features asserts.assert_equal(xml_callable(0x07, [], []), ConformanceDecision.OPTIONAL) + asserts.assert_equal(str(xml_callable), '[AB | CD | EF]') # or term with one of each xml = ('' @@ -514,6 +547,7 @@ async def test_conformance_or_term_with_three_terms(self): asserts.assert_equal(xml_callable(f, a, c), ConformanceDecision.OPTIONAL) else: asserts.assert_equal(xml_callable(f, a, c), ConformanceDecision.NOT_APPLICABLE) + asserts.assert_equal(str(xml_callable), '[AB | attr1 | cmd1]') def test_conformance_otherwise(self): # AB, O @@ -530,6 +564,7 @@ def test_conformance_otherwise(self): asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.MANDATORY) else: asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.OPTIONAL) + asserts.assert_equal(str(xml_callable), 'AB, O') # AB, [CD] xml = ('' @@ -549,6 +584,7 @@ def test_conformance_otherwise(self): asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.OPTIONAL) else: asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.NOT_APPLICABLE) + asserts.assert_equal(str(xml_callable), 'AB, [CD]') # AB & !CD, P xml = ('' @@ -569,6 +605,7 @@ def test_conformance_otherwise(self): asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.MANDATORY) else: asserts.assert_equal(xml_callable(f, [], []), ConformanceDecision.PROVISIONAL) + asserts.assert_equal(str(xml_callable), 'AB & !CD, P') if __name__ == "__main__": diff --git a/src/python_testing/conformance_support.py b/src/python_testing/conformance_support.py index 2dabb584c9d0f7..1d3f3128ef37cd 100644 --- a/src/python_testing/conformance_support.py +++ b/src/python_testing/conformance_support.py @@ -67,74 +67,131 @@ def conformance_allowed(conformance_decision: ConformanceDecision, allow_provisi return True -def mandatory(feature_map: uint, attribute_list: list[uint], all_command_list: list[uint]) -> ConformanceDecision: - return ConformanceDecision.MANDATORY +class mandatory: + def __call__(self, feature_map: uint, attribute_list: list[uint], all_command_list: list[uint]) -> ConformanceDecision: + return ConformanceDecision.MANDATORY + + def __str__(self): + return 'M' + + +class optional: + def __call__(self, feature_map: uint, attribute_list: list[uint], all_command_list: list[uint]) -> ConformanceDecision: + return ConformanceDecision.OPTIONAL + def __str__(self): + return 'O' + + +class deprecated: + def __call__(self, feature_map: uint, attribute_list: list[uint], all_command_list: list[uint]) -> ConformanceDecision: + return ConformanceDecision.DISALLOWED + + def __str__(self): + return 'D' -def optional(feature_map: uint, attribute_list: list[uint], all_command_list: list[uint]) -> ConformanceDecision: - return ConformanceDecision.OPTIONAL +class disallowed: + def __call__(self, feature_map: uint, attribute_list: list[uint], all_command_list: list[uint]) -> ConformanceDecision: + return ConformanceDecision.DISALLOWED -def deprecated(feature_map: uint, attribute_list: list[uint], all_command_list: list[uint]) -> ConformanceDecision: - return ConformanceDecision.DISALLOWED + def __str__(self): + return 'X' -def disallowed(feature_map: uint, attribute_list: list[uint], all_command_list: list[uint]) -> ConformanceDecision: - return ConformanceDecision.DISALLOWED +class provisional: + def __call__(self, feature_map: uint, attribute_list: list[uint], all_command_list: list[uint]) -> ConformanceDecision: + return ConformanceDecision.PROVISIONAL + def __str__(self): + return 'P' -def provisional(feature_map: uint, attribute_list: list[uint], all_command_list: list[uint]) -> ConformanceDecision: - return ConformanceDecision.PROVISIONAL +class feature: + def __init__(self, requiredFeature: uint, code: str): + self.requiredFeature = requiredFeature + self.code = code -def feature(requiredFeature: uint) -> Callable: - def feature_inner(feature_map: uint, attribute_list: list[uint], all_command_list: list[uint]) -> ConformanceDecision: - if requiredFeature & feature_map != 0: + def __call__(self, feature_map: uint, attribute_list: list[uint], all_command_list: list[uint]) -> ConformanceDecision: + if self.requiredFeature & feature_map != 0: return ConformanceDecision.MANDATORY return ConformanceDecision.NOT_APPLICABLE - return feature_inner + def __str__(self): + return f'{self.code}' + + +class attribute: + def __init__(self, requiredAttribute: uint, name: str): + self.requiredAttribute = requiredAttribute + self.name = name -def attribute(requiredAttribute: uint) -> Callable: - def attribute_inner(feature_map: uint, attribute_list: list[uint], all_command_list: list[uint]) -> ConformanceDecision: - if requiredAttribute in attribute_list: + def __call__(self, feature_map: uint, attribute_list: list[uint], all_command_list: list[uint]) -> ConformanceDecision: + if self.requiredAttribute in attribute_list: return ConformanceDecision.MANDATORY return ConformanceDecision.NOT_APPLICABLE - return attribute_inner + def __str__(self): + return f'{self.name}' + + +class command: + def __init__(self, requiredCommand: uint, name: str): + self.requiredCommand = requiredCommand + self.name = name -def command(requiredCommand: uint) -> Callable: - def command_inner(feature_map: uint, attribute_list: list[uint], all_command_list: list[uint]) -> ConformanceDecision: - if requiredCommand in all_command_list: + def __call__(self, feature_map: uint, attribute_list: list[uint], all_command_list: list[uint]) -> ConformanceDecision: + if self.requiredCommand in all_command_list: return ConformanceDecision.MANDATORY return ConformanceDecision.NOT_APPLICABLE - return command_inner + + def __str__(self): + return f'{self.name}' -def optional_wrapper(op: Callable) -> Callable: - def optional_wrapper_inner(feature_map: uint, attribute_list: list[uint], all_command_list: list[uint]) -> ConformanceDecision: - decision = op(feature_map, attribute_list, all_command_list) +def strip_outer_parentheses(inner: str) -> str: + if inner[0] == '(' and inner[-1] == ')': + return inner[1:-1] + return inner + + +class optional_wrapper: + def __init__(self, op: Callable): + self.op = op + + def __call__(self, feature_map: uint, attribute_list: list[uint], all_command_list: list[uint]) -> ConformanceDecision: + decision = self.op(feature_map, attribute_list, all_command_list) if decision == ConformanceDecision.MANDATORY or decision == ConformanceDecision.OPTIONAL: return ConformanceDecision.OPTIONAL elif decision == ConformanceDecision.NOT_APPLICABLE: return ConformanceDecision.NOT_APPLICABLE else: raise ConformanceException(f'Optional wrapping invalid op {decision}') - return optional_wrapper_inner + + def __str__(self): + return f'[{strip_outer_parentheses(str(self.op))}]' -def mandatory_wrapper(op: Callable) -> Callable: - def mandatory_wrapper_inner(feature_map: uint, attribute_list: list[uint], all_command_list: list[uint]) -> ConformanceDecision: - return op(feature_map, attribute_list, all_command_list) - return mandatory_wrapper_inner +class mandatory_wrapper: + def __init__(self, op: Callable): + self.op = op + def __call__(self, feature_map: uint, attribute_list: list[uint], all_command_list: list[uint]) -> ConformanceDecision: + return self.op(feature_map, attribute_list, all_command_list) -def not_operation(op: Callable): - def not_operation_inner(feature_map: uint, attribute_list: list[uint], all_command_list: list[uint]) -> ConformanceDecision: + def __str__(self): + return strip_outer_parentheses(str(self.op)) + + +class not_operation: + def __init__(self, op: Callable): + self.op = op + + def __call__(self, feature_map: uint, attribute_list: list[uint], all_command_list: list[uint]) -> ConformanceDecision: # not operations can't be used with anything that returns DISALLOWED # not operations also can't be used with things that are optional # ie, ![AB] doesn't make sense, nor does !O - decision = op(feature_map, attribute_list, all_command_list) + decision = self.op(feature_map, attribute_list, all_command_list) if decision == ConformanceDecision.OPTIONAL or decision == ConformanceDecision.DISALLOWED or decision == ConformanceDecision.PROVISIONAL: raise ConformanceException('NOT operation on optional or disallowed item') elif decision == ConformanceDecision.NOT_APPLICABLE: @@ -143,12 +200,17 @@ def not_operation_inner(feature_map: uint, attribute_list: list[uint], all_comma return ConformanceDecision.NOT_APPLICABLE else: raise ConformanceException('NOT called on item with non-conformance value') - return not_operation_inner + def __str__(self): + return f'!{str(self.op)}' + + +class and_operation: + def __init__(self, op_list: list[Callable]): + self.op_list = op_list -def and_operation(op_list: list[Callable]) -> Callable: - def and_operation_inner(feature_map: uint, attribute_list: list[uint], all_command_list: list[uint]) -> ConformanceDecision: - for op in op_list: + def __call__(self, feature_map: uint, attribute_list: list[uint], all_command_list: list[uint]) -> ConformanceDecision: + for op in self.op_list: decision = op(feature_map, attribute_list, all_command_list) # and operations can't happen on optional or disallowed if decision == ConformanceDecision.OPTIONAL or decision == ConformanceDecision.DISALLOWED or decision == ConformanceDecision.PROVISIONAL: @@ -160,12 +222,18 @@ def and_operation_inner(feature_map: uint, attribute_list: list[uint], all_comma else: raise ConformanceException('Oplist item returned non-conformance value') return ConformanceDecision.MANDATORY - return and_operation_inner + def __str__(self): + op_strs = [str(op) for op in self.op_list] + return f'({" & ".join(op_strs)})' + + +class or_operation: + def __init__(self, op_list: list[Callable]): + self.op_list = op_list -def or_operation(op_list: list[Callable]) -> Callable: - def or_operation_inner(feature_map: uint, attribute_list: list[uint], all_command_list: list[uint]) -> ConformanceDecision: - for op in op_list: + def __call__(self, feature_map: uint, attribute_list: list[uint], all_command_list: list[uint]) -> ConformanceDecision: + for op in self.op_list: decision = op(feature_map, attribute_list, all_command_list) if decision == ConformanceDecision.DISALLOWED or decision == ConformanceDecision.PROVISIONAL: raise ConformanceException('OR operation on optional or disallowed item') @@ -178,58 +246,67 @@ def or_operation_inner(feature_map: uint, attribute_list: list[uint], all_comman else: raise ConformanceException('Oplist item returned non-conformance value') return ConformanceDecision.NOT_APPLICABLE - return or_operation_inner + + def __str__(self): + op_strs = [str(op) for op in self.op_list] + return f'({" | ".join(op_strs)})' # TODO: add xor operation once it's required # TODO: how would equal and unequal operations work here? -def otherwise(op_list: list[Callable]) -> Callable: - def otherwise_inner(feature_map: uint, attribute_list: list[uint], all_command_list: list[uint]) -> ConformanceDecision: +class otherwise: + def __init__(self, op_list: list[Callable]): + self.op_list = op_list + + def __call__(self, feature_map: uint, attribute_list: list[uint], all_command_list: list[uint]) -> ConformanceDecision: # Otherwise operations apply from left to right. If any of them # has a definite decision (optional, mandatory or disallowed), that is the one that applies # Provisional items are meant to be marked as the first item in the list # Deprecated items are either on their own, or follow an O as O,D. # For O,D, optional applies (leftmost), but we should consider some way to warn here as well, # possibly in another function - for op in op_list: + for op in self.op_list: decision = op(feature_map, attribute_list, all_command_list) if decision == ConformanceDecision.NOT_APPLICABLE: continue return decision return ConformanceDecision.NOT_APPLICABLE - return otherwise_inner + + def __str__(self): + op_strs = [strip_outer_parentheses(str(op)) for op in self.op_list] + return ', '.join(op_strs) def parse_callable_from_xml(element: ElementTree.Element, params: ConformanceParseParameters) -> Callable: if len(list(element)) == 0: # no subchildren here, so this can only be mandatory, optional, provisional, deprecated, disallowed, feature or attribute if element.tag == MANDATORY_CONFORM: - return mandatory + return mandatory() elif element.tag == OPTIONAL_CONFORM: - return optional + return optional() elif element.tag == PROVISIONAL_CONFORM: - return provisional + return provisional() elif element.tag == DEPRECATE_CONFORM: - return deprecated + return deprecated() elif element.tag == DISALLOW_CONFORM: - return disallowed + return disallowed() elif element.tag == FEATURE_TAG: try: - return feature(params.feature_map[element.get('name')]) + return feature(params.feature_map[element.get('name')], element.get('name')) except KeyError: raise ConformanceException(f'Conformance specifies feature not in feature table: {element.get("name")}') elif element.tag == ATTRIBUTE_TAG: # Some command conformance tags are marked as attribute, so if this key isn't in attribute, try command name = element.get('name') if name in params.attribute_map: - return attribute(params.attribute_map[name]) + return attribute(params.attribute_map[name], name) elif name in params.command_map: - return command(params.command_map[name]) + return command(params.command_map[name], name) else: raise ConformanceException(f'Conformance specifies attribute or command not in table: {name}') elif element.tag == COMMAND_TAG: - return command(params.command_map[element.get('name')]) + return command(params.command_map[element.get('name')], element.get('name')) else: raise ConformanceException( f'Unexpected xml conformance element with no children {str(element.tag)} {str(element.attrib)}') From 38fa9022af69e9c7dec0f04597addc81cb21b846 Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Thu, 2 Nov 2023 12:04:48 -0400 Subject: [PATCH 7/8] Make sure kotlin files are kept up to date (#30172) Co-authored-by: Andrei Litvin --- scripts/tools/zap_regen_all.py | 5 + .../clusters/ApplicationLauncherCluster.kt | 11 -- .../clusters/GeneralDiagnosticsCluster.kt | 8 -- .../clusters/MicrowaveOvenModeCluster.kt | 112 ++++++++++++++++++ .../cluster/clusters/OnOffCluster.kt | 2 +- .../matter/devicecontroller/cluster/files.gni | 3 + ...icrowaveOvenModeClusterModeOptionStruct.kt | 76 ++++++++++++ .../MicrowaveOvenModeClusterModeTagStruct.kt | 65 ++++++++++ 8 files changed, 262 insertions(+), 20 deletions(-) create mode 100644 src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/MicrowaveOvenModeCluster.kt create mode 100644 src/controller/java/generated/java/matter/devicecontroller/cluster/structs/MicrowaveOvenModeClusterModeOptionStruct.kt create mode 100644 src/controller/java/generated/java/matter/devicecontroller/cluster/structs/MicrowaveOvenModeClusterModeTagStruct.kt diff --git a/scripts/tools/zap_regen_all.py b/scripts/tools/zap_regen_all.py index a274ea84597a15..6650740c4b734a 100755 --- a/scripts/tools/zap_regen_all.py +++ b/scripts/tools/zap_regen_all.py @@ -433,6 +433,11 @@ def getCodegenTemplates(): idl_path="src/controller/data_model/controller-clusters.matter", output_directory="src/controller/java/generated")) + targets.append(JinjaCodegenTarget( + generator="kotlin-class", + idl_path="src/controller/data_model/controller-clusters.matter", + output_directory="src/controller/java/generated")) + return targets diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ApplicationLauncherCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ApplicationLauncherCluster.kt index 7e07a8ed18e36e..ceec6c2afd73e7 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ApplicationLauncherCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ApplicationLauncherCluster.kt @@ -83,17 +83,6 @@ class ApplicationLauncherCluster(private val endpointId: UShort) { // Implementation needs to be added here } - suspend fun writeCurrentAppAttribute(value: ApplicationLauncherClusterApplicationEPStruct) { - // Implementation needs to be added here - } - - suspend fun writeCurrentAppAttribute( - value: ApplicationLauncherClusterApplicationEPStruct, - timedWriteTimeoutMs: Int - ) { - // Implementation needs to be added here - } - suspend fun subscribeCurrentAppAttribute( minInterval: Int, maxInterval: Int diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/GeneralDiagnosticsCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/GeneralDiagnosticsCluster.kt index 1a3b9d434bc57a..5d6b2222c717f7 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/GeneralDiagnosticsCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/GeneralDiagnosticsCluster.kt @@ -145,14 +145,6 @@ class GeneralDiagnosticsCluster(private val endpointId: UShort) { // Implementation needs to be added here } - suspend fun readAverageWearCountAttribute(): UInt { - // Implementation needs to be added here - } - - suspend fun subscribeAverageWearCountAttribute(minInterval: Int, maxInterval: Int): UInt { - // Implementation needs to be added here - } - suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { // Implementation needs to be added here } diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/MicrowaveOvenModeCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/MicrowaveOvenModeCluster.kt new file mode 100644 index 00000000000000..b09b0be629a172 --- /dev/null +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/MicrowaveOvenModeCluster.kt @@ -0,0 +1,112 @@ +/* + * + * Copyright (c) 2023 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. + */ + +package matter.devicecontroller.cluster.clusters + +import matter.devicecontroller.cluster.structs.* + +class MicrowaveOvenModeCluster(private val endpointId: UShort) { + class SupportedModesAttribute(val value: List) + + class GeneratedCommandListAttribute(val value: List) + + class AcceptedCommandListAttribute(val value: List) + + class EventListAttribute(val value: List) + + class AttributeListAttribute(val value: List) + + suspend fun readSupportedModesAttribute(): SupportedModesAttribute { + // Implementation needs to be added here + } + + suspend fun subscribeSupportedModesAttribute( + minInterval: Int, + maxInterval: Int + ): SupportedModesAttribute { + // Implementation needs to be added here + } + + suspend fun readCurrentModeAttribute(): UByte { + // Implementation needs to be added here + } + + suspend fun subscribeCurrentModeAttribute(minInterval: Int, maxInterval: Int): UByte { + // Implementation needs to be added here + } + + suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { + // Implementation needs to be added here + } + + suspend fun subscribeGeneratedCommandListAttribute( + minInterval: Int, + maxInterval: Int + ): GeneratedCommandListAttribute { + // Implementation needs to be added here + } + + suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { + // Implementation needs to be added here + } + + suspend fun subscribeAcceptedCommandListAttribute( + minInterval: Int, + maxInterval: Int + ): AcceptedCommandListAttribute { + // Implementation needs to be added here + } + + suspend fun readEventListAttribute(): EventListAttribute { + // Implementation needs to be added here + } + + suspend fun subscribeEventListAttribute(minInterval: Int, maxInterval: Int): EventListAttribute { + // Implementation needs to be added here + } + + suspend fun readAttributeListAttribute(): AttributeListAttribute { + // Implementation needs to be added here + } + + suspend fun subscribeAttributeListAttribute( + minInterval: Int, + maxInterval: Int + ): AttributeListAttribute { + // Implementation needs to be added here + } + + suspend fun readFeatureMapAttribute(): UInt { + // Implementation needs to be added here + } + + suspend fun subscribeFeatureMapAttribute(minInterval: Int, maxInterval: Int): UInt { + // Implementation needs to be added here + } + + suspend fun readClusterRevisionAttribute(): UShort { + // Implementation needs to be added here + } + + suspend fun subscribeClusterRevisionAttribute(minInterval: Int, maxInterval: Int): UShort { + // Implementation needs to be added here + } + + companion object { + const val CLUSTER_ID: UInt = 94u + } +} diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/OnOffCluster.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/OnOffCluster.kt index 912d623f0e8bbe..0a71a64888a866 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/OnOffCluster.kt +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/OnOffCluster.kt @@ -56,7 +56,7 @@ class OnOffCluster(private val endpointId: UShort) { suspend fun offWithEffect( effectIdentifier: UInt, - effectVariant: UByte, + effectVariant: UInt, timedInvokeTimeoutMs: Int? = null ) { if (timedInvokeTimeoutMs != null) { diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/files.gni b/src/controller/java/generated/java/matter/devicecontroller/cluster/files.gni index 0788d700b4f130..25bafdf86f1d13 100644 --- a/src/controller/java/generated/java/matter/devicecontroller/cluster/files.gni +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/files.gni @@ -41,6 +41,8 @@ matter_structs_sources = [ "${chip_root}/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/LaundryWasherModeClusterModeTagStruct.kt", "${chip_root}/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/MediaInputClusterInputInfoStruct.kt", "${chip_root}/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/MediaPlaybackClusterPlaybackPositionStruct.kt", + "${chip_root}/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/MicrowaveOvenModeClusterModeOptionStruct.kt", + "${chip_root}/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/MicrowaveOvenModeClusterModeTagStruct.kt", "${chip_root}/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/ModeSelectClusterModeOptionStruct.kt", "${chip_root}/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/ModeSelectClusterSemanticTagStruct.kt", "${chip_root}/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/NetworkCommissioningClusterNetworkInfoStruct.kt", @@ -192,6 +194,7 @@ matter_clusters_sources = [ "${chip_root}/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/MediaInputCluster.kt", "${chip_root}/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/MediaPlaybackCluster.kt", "${chip_root}/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/MicrowaveOvenControlCluster.kt", + "${chip_root}/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/MicrowaveOvenModeCluster.kt", "${chip_root}/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/ModeSelectCluster.kt", "${chip_root}/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/NetworkCommissioningCluster.kt", "${chip_root}/src/controller/java/generated/java/matter/devicecontroller/cluster/clusters/NitrogenDioxideConcentrationMeasurementCluster.kt", diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/MicrowaveOvenModeClusterModeOptionStruct.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/MicrowaveOvenModeClusterModeOptionStruct.kt new file mode 100644 index 00000000000000..481ae34118a03b --- /dev/null +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/MicrowaveOvenModeClusterModeOptionStruct.kt @@ -0,0 +1,76 @@ +/* + * + * Copyright (c) 2023 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. + */ +package matter.devicecontroller.cluster.structs + +import matter.devicecontroller.cluster.* +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.Tag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter + +class MicrowaveOvenModeClusterModeOptionStruct( + val label: String, + val mode: UByte, + val modeTags: List +) { + override fun toString(): String = buildString { + append("MicrowaveOvenModeClusterModeOptionStruct {\n") + append("\tlabel : $label\n") + append("\tmode : $mode\n") + append("\tmodeTags : $modeTags\n") + append("}\n") + } + + fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { + tlvWriter.apply { + startStructure(tlvTag) + put(ContextSpecificTag(TAG_LABEL), label) + put(ContextSpecificTag(TAG_MODE), mode) + startArray(ContextSpecificTag(TAG_MODE_TAGS)) + for (item in modeTags.iterator()) { + item.toTlv(AnonymousTag, this) + } + endArray() + endStructure() + } + } + + companion object { + private const val TAG_LABEL = 0 + private const val TAG_MODE = 1 + private const val TAG_MODE_TAGS = 2 + + fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): MicrowaveOvenModeClusterModeOptionStruct { + tlvReader.enterStructure(tlvTag) + val label = tlvReader.getString(ContextSpecificTag(TAG_LABEL)) + val mode = tlvReader.getUByte(ContextSpecificTag(TAG_MODE)) + val modeTags = + buildList { + tlvReader.enterArray(ContextSpecificTag(TAG_MODE_TAGS)) + while (!tlvReader.isEndOfContainer()) { + add(MicrowaveOvenModeClusterModeTagStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + + tlvReader.exitContainer() + + return MicrowaveOvenModeClusterModeOptionStruct(label, mode, modeTags) + } + } +} diff --git a/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/MicrowaveOvenModeClusterModeTagStruct.kt b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/MicrowaveOvenModeClusterModeTagStruct.kt new file mode 100644 index 00000000000000..d0d088a1d77b42 --- /dev/null +++ b/src/controller/java/generated/java/matter/devicecontroller/cluster/structs/MicrowaveOvenModeClusterModeTagStruct.kt @@ -0,0 +1,65 @@ +/* + * + * Copyright (c) 2023 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. + */ +package matter.devicecontroller.cluster.structs + +import java.util.Optional +import matter.devicecontroller.cluster.* +import matter.tlv.ContextSpecificTag +import matter.tlv.Tag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter + +class MicrowaveOvenModeClusterModeTagStruct(val mfgCode: Optional, val value: UInt) { + override fun toString(): String = buildString { + append("MicrowaveOvenModeClusterModeTagStruct {\n") + append("\tmfgCode : $mfgCode\n") + append("\tvalue : $value\n") + append("}\n") + } + + fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { + tlvWriter.apply { + startStructure(tlvTag) + if (mfgCode.isPresent) { + val optmfgCode = mfgCode.get() + put(ContextSpecificTag(TAG_MFG_CODE), optmfgCode) + } + put(ContextSpecificTag(TAG_VALUE), value) + endStructure() + } + } + + companion object { + private const val TAG_MFG_CODE = 0 + private const val TAG_VALUE = 1 + + fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): MicrowaveOvenModeClusterModeTagStruct { + tlvReader.enterStructure(tlvTag) + val mfgCode = + if (tlvReader.isNextTag(ContextSpecificTag(TAG_MFG_CODE))) { + Optional.of(tlvReader.getUShort(ContextSpecificTag(TAG_MFG_CODE))) + } else { + Optional.empty() + } + val value = tlvReader.getUInt(ContextSpecificTag(TAG_VALUE)) + + tlvReader.exitContainer() + + return MicrowaveOvenModeClusterModeTagStruct(mfgCode, value) + } + } +} From 71a72aea02e8aee88a76006e5f18567b68837d59 Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Thu, 2 Nov 2023 12:09:57 -0400 Subject: [PATCH 8/8] Add a "Darwin force write" configuration for darwin APIs (#30174) * Start adding darwin backwards compatibility * Update conditional and also fix MTRClusters source * Alter the files and zap regen --------- Co-authored-by: Andrei Litvin --- src/app/common/templates/config-data.yaml | 5 ++ .../CHIP/templates/MTRBaseClusters-src.zapt | 6 ++- .../CHIP/templates/MTRBaseClusters.zapt | 6 ++- .../CHIP/templates/MTRClusters-src.zapt | 6 ++- .../Framework/CHIP/templates/MTRClusters.zapt | 6 ++- .../Framework/CHIP/templates/templates.json | 3 +- .../CHIP/zap-generated/MTRBaseClusters.h | 4 ++ .../CHIP/zap-generated/MTRBaseClusters.mm | 46 +++++++++++++++++++ .../CHIP/zap-generated/MTRClusters.h | 2 + .../CHIP/zap-generated/MTRClusters.mm | 11 +++++ 10 files changed, 86 insertions(+), 9 deletions(-) diff --git a/src/app/common/templates/config-data.yaml b/src/app/common/templates/config-data.yaml index 4f8eb12c39e689..60fc765d26f403 100644 --- a/src/app/common/templates/config-data.yaml +++ b/src/app/common/templates/config-data.yaml @@ -1,3 +1,8 @@ +DarwinForceWritable: + # Work-around for not allowing changes from writable to read-only + # happened in https://github.com/project-chip/connectedhomeip/pull/30134 + - ApplicationLauncher::CurrentApp + WeakEnums: # Allow-list of enums that we generate as enums, not enum classes. # The goal is to drive this down to 0. diff --git a/src/darwin/Framework/CHIP/templates/MTRBaseClusters-src.zapt b/src/darwin/Framework/CHIP/templates/MTRBaseClusters-src.zapt index fa249b734ee90a..8097b929e06e9a 100644 --- a/src/darwin/Framework/CHIP/templates/MTRBaseClusters-src.zapt +++ b/src/darwin/Framework/CHIP/templates/MTRBaseClusters-src.zapt @@ -151,7 +151,8 @@ MTR{{cluster}}Cluster{{command}}Params completion:completion]; } -{{#if isWritableAttribute}} +{{#if (or isWritableAttribute + (isInConfigList (concat (asUpperCamelCase parent.name) "::" label) "DarwinForceWritable"))}} - (void)write{{>attribute}}WithValue:({{asObjectiveCType type parent.name}})value completion:(MTRStatusCompletion)completion { [self write{{>attribute}}WithValue:({{asObjectiveCType type parent.name}})value params:nil completion:completion]; @@ -292,7 +293,8 @@ reportHandler:(void (^)({{asObjectiveCClass type parent.name}} * _Nullable value completionHandler(static_cast<{{asObjectiveCClass type parent.name compatRemapClusterName=true}} *>(value), error); }]; } -{{#if isWritableAttribute}} +{{#if (or isWritableAttribute + (isInConfigList (concat (asUpperCamelCase parent.name) "::" label) "DarwinForceWritable"))}} - (void)write{{>attribute}}WithValue:({{asObjectiveCType type parent.name compatRemapClusterName=true}})value completionHandler:(MTRStatusCompletion)completionHandler { [self writeAttribute{{asUpperCamelCase name preserveAcronyms=true}}WithValue:value params:nil completion:completionHandler]; diff --git a/src/darwin/Framework/CHIP/templates/MTRBaseClusters.zapt b/src/darwin/Framework/CHIP/templates/MTRBaseClusters.zapt index 71a37db8356c94..52047a1fa2fbc6 100644 --- a/src/darwin/Framework/CHIP/templates/MTRBaseClusters.zapt +++ b/src/darwin/Framework/CHIP/templates/MTRBaseClusters.zapt @@ -65,7 +65,8 @@ NS_ASSUME_NONNULL_BEGIN Completion: {{~/if_is_fabric_scoped_struct~}} (void (^)({{asObjectiveCClass type parent.name}} * _Nullable value, NSError * _Nullable error))completion {{availability (asUpperCamelCase parent.name preserveAcronyms=true) attribute=(asUpperCamelCase name preserveAcronyms=true) minimalRelease="First major API revamp"}}; -{{#if isWritableAttribute}} +{{#if (or isWritableAttribute + (isInConfigList (concat (asUpperCamelCase parent.name) "::" label) "DarwinForceWritable"))}} - (void)write{{>attribute}}WithValue:({{asObjectiveCType type parent.name}})value completion:(MTRStatusCompletion)completion {{availability (asUpperCamelCase parent.name preserveAcronyms=true) attribute=(asUpperCamelCase name preserveAcronyms=true) minimalRelease="First major API revamp"}}; - (void)write{{>attribute}}WithValue:({{asObjectiveCType type parent.name}})value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion {{availability (asUpperCamelCase parent.name preserveAcronyms=true) attribute=(asUpperCamelCase name preserveAcronyms=true) minimalRelease="First major API revamp"}}; {{/if}} @@ -238,7 +239,8 @@ typedef NS_OPTIONS({{asUnderlyingZclType name}}, {{objCEnumName clusterName bitm CompletionHandler: {{~/if_is_fabric_scoped_struct~}} (void (^)({{asObjectiveCClass type parent.name compatRemapClusterName=true}} * _Nullable value, NSError * _Nullable error))completionHandler {{availability (compatClusterNameRemapping parent.name) attribute=(compatAttributeNameRemapping parent.name name) deprecatedRelease="First major API revamp" fabricScopedDeprecationMessage=(concat "Please use readAttribute" (asUpperCamelCase name preserveAcronyms=true) "WithParams:completion:") nonFabricScopedDeprecationMessage=(concat "Please use readAttribute" (asUpperCamelCase name preserveAcronyms=true) "WithCompletion:") type=type}}; -{{#if isWritableAttribute}} +{{#if (or isWritableAttribute + (isInConfigList (concat (asUpperCamelCase parent.name) "::" label) "DarwinForceWritable"))}} - (void)write{{>attribute}}WithValue:({{asObjectiveCType type parent.name compatRemapClusterName=true}})value completionHandler:(MTRStatusCompletion)completionHandler {{availability (compatClusterNameRemapping parent.name) attribute=(compatAttributeNameRemapping parent.name name) deprecatedRelease="First major API revamp" deprecationMessage=(concat "Please use writeAttribute" (asUpperCamelCase name preserveAcronyms=true) "WithValue:completion:")}}; - (void)write{{>attribute}}WithValue:({{asObjectiveCType type parent.name compatRemapClusterName=true}})value params:(MTRWriteParams * _Nullable)params completionHandler:(MTRStatusCompletion)completionHandler {{availability (compatClusterNameRemapping parent.name) attribute=(compatAttributeNameRemapping parent.name name) deprecatedRelease="First major API revamp" deprecationMessage=(concat "Please use writeAttribute" (asUpperCamelCase name preserveAcronyms=true) "WithValue:params:completion:")}}; {{/if}} diff --git a/src/darwin/Framework/CHIP/templates/MTRClusters-src.zapt b/src/darwin/Framework/CHIP/templates/MTRClusters-src.zapt index 617beb92815d92..4a2c566785ef68 100644 --- a/src/darwin/Framework/CHIP/templates/MTRClusters-src.zapt +++ b/src/darwin/Framework/CHIP/templates/MTRClusters-src.zapt @@ -123,7 +123,8 @@ MTR{{cluster}}Cluster{{command}}Params return [self.device readAttributeWithEndpointID:@(self.endpoint) clusterID:@(MTRClusterIDType{{>cluster}}ID) attributeID:@(MTRAttributeIDTypeCluster{{>cluster}}{{>attribute}}ID) params:params]; } -{{#if isWritableAttribute}} +{{#if (or isWritableAttribute + (isInConfigList (concat (asUpperCamelCase parent.name) "::" label) "DarwinForceWritable"))}} {{#*inline "callbackName"}}DefaultSuccess{{/inline}} - (void)write{{>attribute}}WithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs { @@ -207,7 +208,8 @@ MTR{{cluster}}Cluster{{command}}Params { return [self readAttribute{{asUpperCamelCase name preserveAcronyms=true}}WithParams:params]; } -{{#if isWritableAttribute}} +{{#if (or isWritableAttribute + (isInConfigList (concat (asUpperCamelCase parent.name) "::" label) "DarwinForceWritable"))}} - (void)writeAttribute{{attribute}}WithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs { [self writeAttribute{{asUpperCamelCase name preserveAcronyms=true}}WithValue:dataValueDictionary expectedValueInterval:expectedValueIntervalMs]; diff --git a/src/darwin/Framework/CHIP/templates/MTRClusters.zapt b/src/darwin/Framework/CHIP/templates/MTRClusters.zapt index 84e27d675ee59a..17ef4f741dd6f8 100644 --- a/src/darwin/Framework/CHIP/templates/MTRClusters.zapt +++ b/src/darwin/Framework/CHIP/templates/MTRClusters.zapt @@ -71,7 +71,8 @@ NS_ASSUME_NONNULL_BEGIN {{availability (asUpperCamelCase parent.name preserveAcronyms=true) attribute=(asUpperCamelCase name preserveAcronyms=true)}} {{/inline}} - (NSDictionary * _Nullable)read{{>attribute}}WithParams:(MTRReadParams * _Nullable)params {{> availability}}; -{{#if isWritableAttribute}} +{{#if (or isWritableAttribute + (isInConfigList (concat (asUpperCamelCase parent.name) "::" label) "DarwinForceWritable"))}} - (void)write{{>attribute}}WithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs {{> availability}}; - (void)write{{>attribute}}WithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params {{> availability}}; {{/if}} @@ -130,7 +131,8 @@ NS_ASSUME_NONNULL_BEGIN {{~#*inline "attributeDecls"}} {{#unless (isStrEqual attribute (asUpperCamelCase name preserveAcronyms=true))}} - (NSDictionary *)readAttribute{{attribute}}WithParams:(MTRReadParams * _Nullable)params {{availability cluster attribute=attribute deprecatedRelease="First major API revamp" deprecationMessage=(concat "Please use readAttribute" (asUpperCamelCase name preserveAcronyms=true) "WithParams on MTRCluster" (asUpperCamelCase parent.name preserveAcronyms=true))}}; -{{#if isWritableAttribute}} +{{#if (or isWritableAttribute + (isInConfigList (concat (asUpperCamelCase parent.name) "::" label) "DarwinForceWritable"))}} - (void)writeAttribute{{attribute}}WithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs {{availability cluster attribute=attribute deprecationMessage=(concat "Please use writeAttribute" (asUpperCamelCase name preserveAcronyms=true) "WithValue on MTRCluster" (asUpperCamelCase parent.name preserveAcronyms=true))}}; - (void)writeAttribute{{attribute}}WithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params {{availability cluster attribute=attribute deprecationMessage=(concat "Please use writeAttribute" (asUpperCamelCase name preserveAcronyms=true) "WithValue on MTRCluster" (asUpperCamelCase parent.name preserveAcronyms=true))}}; {{/if}} diff --git a/src/darwin/Framework/CHIP/templates/templates.json b/src/darwin/Framework/CHIP/templates/templates.json index 89c101a30d77e2..83b001285cfcf2 100644 --- a/src/darwin/Framework/CHIP/templates/templates.json +++ b/src/darwin/Framework/CHIP/templates/templates.json @@ -11,7 +11,8 @@ "darwin/Framework/CHIP/templates/helper.js" ], "resources": { - "availability-data": "availability.yaml" + "availability-data": "availability.yaml", + "config-data": "../../../../app/common/templates/config-data.yaml" }, "override": "../../../../../src/app/zap-templates/common/override.js", "partials": [ diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h index 3a8d94a8b82028..7cfc7faf4da5ad 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h @@ -11347,6 +11347,8 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) + (void)readAttributeCatalogListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)readAttributeCurrentAppWithCompletion:(void (^)(MTRApplicationLauncherClusterApplicationEPStruct * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +- (void)writeAttributeCurrentAppWithValue:(MTRApplicationLauncherClusterApplicationEPStruct * _Nullable)value completion:(MTRStatusCompletion)completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +- (void)writeAttributeCurrentAppWithValue:(MTRApplicationLauncherClusterApplicationEPStruct * _Nullable)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)subscribeAttributeCurrentAppWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished reportHandler:(void (^)(MTRApplicationLauncherClusterApplicationEPStruct * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); @@ -23336,6 +23338,8 @@ typedef NS_OPTIONS(uint8_t, MTRTestClusterSimpleBitmap) { + (void)readAttributeCatalogListWithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completionHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler MTR_DEPRECATED("Please use readAttributeCatalogListWithAttributeCache:endpoint:queue:completion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); - (void)readAttributeCurrentAppWithCompletionHandler:(void (^)(MTRApplicationLauncherClusterApplicationEP * _Nullable value, NSError * _Nullable error))completionHandler MTR_DEPRECATED("Please use readAttributeCurrentAppWithCompletion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); +- (void)writeAttributeCurrentAppWithValue:(MTRApplicationLauncherClusterApplicationEP * _Nullable)value completionHandler:(MTRStatusCompletion)completionHandler MTR_DEPRECATED("Please use writeAttributeCurrentAppWithValue:completion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); +- (void)writeAttributeCurrentAppWithValue:(MTRApplicationLauncherClusterApplicationEP * _Nullable)value params:(MTRWriteParams * _Nullable)params completionHandler:(MTRStatusCompletion)completionHandler MTR_DEPRECATED("Please use writeAttributeCurrentAppWithValue:params:completion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); - (void)subscribeAttributeCurrentAppWithMinInterval:(NSNumber * _Nonnull)minInterval maxInterval:(NSNumber * _Nonnull)maxInterval params:(MTRSubscribeParams * _Nullable)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm index bbc9a343eacf9f..390b5042da3c6b 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm @@ -90159,6 +90159,44 @@ - (void)readAttributeCurrentAppWithCompletion:(void (^)(MTRApplicationLauncherCl completion:completion]; } +- (void)writeAttributeCurrentAppWithValue:(MTRApplicationLauncherClusterApplicationEPStruct * _Nullable)value completion:(MTRStatusCompletion)completion +{ + [self writeAttributeCurrentAppWithValue:(MTRApplicationLauncherClusterApplicationEPStruct * _Nullable) value params:nil completion:completion]; +} +- (void)writeAttributeCurrentAppWithValue:(MTRApplicationLauncherClusterApplicationEPStruct * _Nullable)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion +{ + // Make a copy of params before we go async. + params = [params copy]; + value = [value copy]; + + auto * bridge = new MTRDefaultSuccessCallbackBridge(self.callbackQueue, ^(id _Nullable ignored, NSError * _Nullable error) { completion(error); }, ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb, MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) { + chip::Optional timedWriteTimeout; + if (params != nil) { + if (params.timedWriteTimeout != nil){ + timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue); + } + } + + ListFreer listFreer; + using TypeInfo = ApplicationLauncher::Attributes::CurrentApp::TypeInfo; + TypeInfo::Type cppValue; + if (value == nil) { + cppValue.SetNull(); + } else { + auto & nonNullValue_0 = cppValue.SetNonNull(); + nonNullValue_0.application.catalogVendorID = value.application.catalogVendorID.unsignedShortValue; + nonNullValue_0.application.applicationID = AsCharSpan(value.application.applicationID); + if (value.endpoint != nil) { + auto & definedValue_2 = nonNullValue_0.endpoint.Emplace(); + definedValue_2 = value.endpoint.unsignedShortValue; + } + } + + chip::Controller::ClusterBase cppCluster(exchangeManager, session, self.endpoint); + return cppCluster.WriteAttribute(cppValue, bridge, successCb, failureCb, timedWriteTimeout); }); + std::move(*bridge).DispatchAction(self.device); +} + - (void)subscribeAttributeCurrentAppWithParams:(MTRSubscribeParams * _Nonnull)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished reportHandler:(void (^)(MTRApplicationLauncherClusterApplicationEPStruct * _Nullable value, NSError * _Nullable error))reportHandler @@ -90472,6 +90510,14 @@ - (void)readAttributeCurrentAppWithCompletionHandler:(void (^)(MTRApplicationLau completionHandler(static_cast(value), error); }]; } +- (void)writeAttributeCurrentAppWithValue:(MTRApplicationLauncherClusterApplicationEP * _Nullable)value completionHandler:(MTRStatusCompletion)completionHandler +{ + [self writeAttributeCurrentAppWithValue:value params:nil completion:completionHandler]; +} +- (void)writeAttributeCurrentAppWithValue:(MTRApplicationLauncherClusterApplicationEP * _Nullable)value params:(MTRWriteParams * _Nullable)params completionHandler:(MTRStatusCompletion)completionHandler +{ + [self writeAttributeCurrentAppWithValue:value params:params completion:completionHandler]; +} - (void)subscribeAttributeCurrentAppWithMinInterval:(NSNumber * _Nonnull)minInterval maxInterval:(NSNumber * _Nonnull)maxInterval params:(MTRSubscribeParams * _Nullable)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h index 34708920240ccb..19bdd9d688f301 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h @@ -5540,6 +5540,8 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) - (NSDictionary * _Nullable)readAttributeCatalogListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); - (NSDictionary * _Nullable)readAttributeCurrentAppWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); +- (void)writeAttributeCurrentAppWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); +- (void)writeAttributeCurrentAppWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); - (NSDictionary * _Nullable)readAttributeGeneratedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm index 72410d9fb18507..1684d5a86f5095 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm @@ -16716,6 +16716,17 @@ - (void)hideAppWithParams:(MTRApplicationLauncherClusterHideAppParams * _Nullabl return [self.device readAttributeWithEndpointID:@(self.endpoint) clusterID:@(MTRClusterIDTypeApplicationLauncherID) attributeID:@(MTRAttributeIDTypeClusterApplicationLauncherAttributeCurrentAppID) params:params]; } +- (void)writeAttributeCurrentAppWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs +{ + [self writeAttributeCurrentAppWithValue:dataValueDictionary expectedValueInterval:expectedValueIntervalMs params:nil]; +} +- (void)writeAttributeCurrentAppWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params +{ + NSNumber * timedWriteTimeout = params.timedWriteTimeout; + + [self.device writeAttributeWithEndpointID:@(self.endpoint) clusterID:@(MTRClusterIDTypeApplicationLauncherID) attributeID:@(MTRAttributeIDTypeClusterApplicationLauncherAttributeCurrentAppID) value:dataValueDictionary expectedValueInterval:expectedValueIntervalMs timedWriteTimeout:timedWriteTimeout]; +} + - (NSDictionary * _Nullable)readAttributeGeneratedCommandListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:@(self.endpoint) clusterID:@(MTRClusterIDTypeApplicationLauncherID) attributeID:@(MTRAttributeIDTypeClusterApplicationLauncherAttributeGeneratedCommandListID) params:params];