From 09833eb3d71148cbc38c126523406249f57cae48 Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Wed, 5 Feb 2025 21:19:57 -0500 Subject: [PATCH 01/39] Make global attributes be part of IM instead of part of DataModel::Provider (#37345) * A first pass to add global attributes as part of IME instead of datamodel::provider * Some updates * Update some tests and reformat... the checks were PAINFUL,kept debug logs * Bump test: we now support the extra 3 global attributes not in metadata * More fixes * Fix compile error about parameter shadowing * More updates on casts to make xtensa compile happy * Restyled by clang-format * Fix tests * Make the test for unsupported write consistent with #37322 * Fix includes * Smaller delta * Attribute metadata is now guaranteed * Update src/app/data-model-provider/MetadataLookup.h Co-authored-by: Boris Zbarsky * Update src/app/data-model-provider/MetadataLookup.h Co-authored-by: Boris Zbarsky * Update src/app/reporting/Engine.cpp Co-authored-by: Boris Zbarsky * Update src/app/reporting/Engine.cpp Co-authored-by: Boris Zbarsky * Address some code review comments * Remove the ember metadata public cluster path validation as it is not needed anymore as a public API * Do not enforce ordering in attribute list encoding * Comment about items returned or not returned in various calls * Correct the unsupported attribute call * Restyle * Update order dependent test in java ... this is somewhat broken... * Fix indent * Fix include * Fix typo * Allow TODO comment: I am not willing to re-build the kotlin code right now for this PR * Using uint64_t for encoding saves some flash * Fix test ... although this is NOT ok as we need order independent test * Fix the real list now * Switch the basic information constraints as a set compare (use python) * Remove extra space * Restyled by prettier-yaml * Fix asserts in DGWIFI - wrong method used * Restyled by autopep8 * Update src/app/data-model-provider/Provider.h Co-authored-by: Boris Zbarsky * Update src/app/data-model-provider/ProviderMetadataTree.h Co-authored-by: Boris Zbarsky * Update src/data-model-providers/codegen/CodegenDataModelProvider_Write.cpp Co-authored-by: Boris Zbarsky * Update src/app/data-model-provider/ProviderMetadataTree.h Co-authored-by: Boris Zbarsky * Undo DFWIFI changes, leave it up to #37382. * Update ordering of attribute list to match unsorted (and smaller) implementation in the SDK * Update src/app/GlobalAttributes.cpp Co-authored-by: Terence Hampson * Update src/app/GlobalAttributes.h Co-authored-by: Terence Hampson * Add comment about oddify in path validation * Added comments about why we do the casts ... it is ugly * Add integration test for writing read only attributes and getting the correct error * Restyled by isort * Fix unused imports --------- Co-authored-by: Andrei Litvin Co-authored-by: Restyled.io Co-authored-by: Boris Zbarsky Co-authored-by: Terence Hampson --- .github/workflows/lint.yml | 2 - .../pairing/PairOnNetworkLongImReadCommand.kt | 4 +- kotlin-detect-config.yaml | 1 + scripts/build_coverage.sh | 6 +- src/app/BUILD.gn | 8 +- src/app/GlobalAttributes.cpp | 132 ++++++++++++++++++ src/app/GlobalAttributes.h | 28 ++-- src/app/chip_data_model.cmake | 1 - src/app/chip_data_model.gni | 1 - .../data-model-provider/MetadataLookup.cpp | 21 +++ src/app/data-model-provider/MetadataLookup.h | 8 ++ src/app/data-model-provider/Provider.h | 8 +- .../ProviderMetadataTree.h | 8 ++ .../StringBuilderAdapters.cpp | 12 ++ .../StringBuilderAdapters.h | 9 ++ src/app/reporting/Engine.cpp | 15 +- src/app/tests/TestReadInteraction.cpp | 113 +++++++++++++-- .../tests/suites/TestBasicInformation.yaml | 122 ++++++++-------- ...mber-global-attribute-access-interface.cpp | 121 ---------------- .../ember-global-attribute-access-interface.h | 56 -------- src/app/util/mock/BUILD.gn | 1 - src/controller/tests/data_model/TestRead.cpp | 21 +-- .../CHIPTests/MTRPerControllerStorageTests.m | 6 +- .../Matter.xcodeproj/project.pbxproj | 6 - .../codegen/CodegenDataModelProvider_Read.cpp | 24 +--- .../CodegenDataModelProvider_Write.cpp | 21 ++- .../codegen/EmberMetadata.cpp | 51 ++----- .../codegen/EmberMetadata.h | 12 +- .../codegen/tests/BUILD.gn | 1 - .../tests/TestCodegenModelViaMocks.cpp | 56 -------- .../TestWriteReadOnlyAttributes.py | 115 +++++++++++++++ 31 files changed, 562 insertions(+), 428 deletions(-) create mode 100644 src/app/GlobalAttributes.cpp delete mode 100644 src/app/util/ember-global-attribute-access-interface.cpp delete mode 100644 src/app/util/ember-global-attribute-access-interface.h create mode 100644 src/python_testing/TestWriteReadOnlyAttributes.py diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 3abc726c30..6d5a272c0e 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -114,7 +114,6 @@ jobs: --known-failure app/util/config.h \ --known-failure app/util/DataModelHandler.cpp \ --known-failure app/util/DataModelHandler.h \ - --known-failure app/util/ember-global-attribute-access-interface.h \ --known-failure app/util/ember-io-storage.h \ --known-failure app/util/endpoint-config-api.h \ --known-failure app/util/generic-callbacks.h \ @@ -133,7 +132,6 @@ jobs: # for them. Keeping them as a list as they still need review ... # --known-failure app/util/attribute-table.cpp \ # --known-failure app/util/ember-io-storage.cpp \ - # --known-failure app/util/ember-global-attribute-access-interface.cpp \ # --known-failure app/util/attribute-storage.cpp \ - name: Check for matter lint errors if: always() diff --git a/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkLongImReadCommand.kt b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkLongImReadCommand.kt index 1758fbd868..ff9cd06d43 100644 --- a/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkLongImReadCommand.kt +++ b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkLongImReadCommand.kt @@ -58,10 +58,12 @@ class PairOnNetworkLongImReadCommand( event.getJson().toString() == """{"0:STRUCT":{"0:UINT":1}}""" fun checkAllAttributesJsonForFixedLabel(cluster: String): Boolean { + // TODO: this hard-codes the array and as a result it is order-dependend. This should + // be changed to be order-independent. val expected = """{"65528:ARRAY-?":[],"0:ARRAY-STRUCT":[{"0:STRING":"room","1:STRING":"bedroom 2"},""" + """{"0:STRING":"orientation","1:STRING":"North"},{"0:STRING":"floor","1:STRING":"2"},""" + - """{"0:STRING":"direction","1:STRING":"up"}],"65531:ARRAY-UINT":[0,65528,65529,65531,65532,65533],""" + + """{"0:STRING":"direction","1:STRING":"up"}],"65531:ARRAY-UINT":[0,65532,65533,65528,65529,65531],""" + """"65533:UINT":1,"65529:ARRAY-?":[],"65532:UINT":0}""" return cluster.equals(expected) } diff --git a/kotlin-detect-config.yaml b/kotlin-detect-config.yaml index 622f7a73c1..d0bc6b9ed0 100644 --- a/kotlin-detect-config.yaml +++ b/kotlin-detect-config.yaml @@ -164,6 +164,7 @@ style: - "**/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/MultiAdminClientFragment.kt" - "**/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/clusterinteraction/ClusterInteractionFragment.kt" - "**/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/provisioning/AddressCommissioningFragment.kt" + - "**/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkLongImReadCommand.kt" - "**/src/controller/java/src/matter/onboardingpayload/QRCodeOnboardingPayloadParser.kt" ExplicitItLambdaParameter: excludes: diff --git a/scripts/build_coverage.sh b/scripts/build_coverage.sh index ef6e7b9705..b754d0edaa 100755 --- a/scripts/build_coverage.sh +++ b/scripts/build_coverage.sh @@ -176,9 +176,9 @@ if [ "$skip_gn" == false ]; then fi mkdir -p "$COVERAGE_ROOT" -lcov --initial --capture --directory "$OUTPUT_ROOT/obj/src" --exclude="$PWD"/zzz_generated/* --exclude="$PWD"/third_party/* --exclude=/usr/include/* --output-file "$COVERAGE_ROOT/lcov_base.info" -lcov --capture --directory "$OUTPUT_ROOT/obj/src" --exclude="$PWD"/zzz_generated/* --exclude="$PWD"/third_party/* --exclude=/usr/include/* --output-file "$COVERAGE_ROOT/lcov_test.info" -lcov --add-tracefile "$COVERAGE_ROOT/lcov_base.info" --add-tracefile "$COVERAGE_ROOT/lcov_test.info" --output-file "$COVERAGE_ROOT/lcov_final.info" +lcov --initial --capture --ignore-errors inconsistent --directory "$OUTPUT_ROOT/obj/src" --exclude="$PWD"/zzz_generated/* --exclude="$PWD"/third_party/* --exclude=/usr/include/* --output-file "$COVERAGE_ROOT/lcov_base.info" +lcov --capture --ignore-errors inconsistent --directory "$OUTPUT_ROOT/obj/src" --exclude="$PWD"/zzz_generated/* --exclude="$PWD"/third_party/* --exclude=/usr/include/* --output-file "$COVERAGE_ROOT/lcov_test.info" +lcov --ignore-errors inconsistent --add-tracefile "$COVERAGE_ROOT/lcov_base.info" --add-tracefile "$COVERAGE_ROOT/lcov_test.info" --output-file "$COVERAGE_ROOT/lcov_final.info" genhtml "$COVERAGE_ROOT/lcov_final.info" --output-directory "$COVERAGE_ROOT/html" --title "SHA:$(git rev-parse HEAD)" --header-title "Matter SDK Coverage Report" # Copy webapp's YAML file to the coverage output directory diff --git a/src/app/BUILD.gn b/src/app/BUILD.gn index 642f6ee4b5..1a6d84ca28 100644 --- a/src/app/BUILD.gn +++ b/src/app/BUILD.gn @@ -107,17 +107,22 @@ source_set("paths") { "${chip_root}/src/app/util:types", "${chip_root}/src/lib/core", "${chip_root}/src/lib/core:types", + "${chip_root}/src/lib/support", ] } source_set("global-attributes") { - sources = [ "GlobalAttributes.h" ] + sources = [ + "GlobalAttributes.cpp", + "GlobalAttributes.h", + ] # This also depends on zap-generated code which is currently impossible to split out # as a dependency public_deps = [ ":app_config", "${chip_root}/src/app/common:ids", + "${chip_root}/src/app/data-model-provider", "${chip_root}/src/lib/support", ] } @@ -263,7 +268,6 @@ static_library("interaction-model") { # We likely should formalize and change this with a proper DataModel::Provider that # is consistent instead sources += [ - "${chip_root}/src/app/util/ember-global-attribute-access-interface.cpp", "${chip_root}/src/app/util/ember-io-storage.cpp", "dynamic_server/DynamicDispatcher.cpp", ] diff --git a/src/app/GlobalAttributes.cpp b/src/app/GlobalAttributes.cpp new file mode 100644 index 0000000000..a65f79b22b --- /dev/null +++ b/src/app/GlobalAttributes.cpp @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2022-2025 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include + +using chip::Protocols::InteractionModel::Status; + +namespace chip { +namespace app { + +bool IsSupportedGlobalAttributeNotInMetadata(AttributeId attributeId) +{ + for (auto & attr : GlobalAttributesNotInMetadata) + { + if (attr == attributeId) + { + return true; + } + } + + return false; +} + +DataModel::ActionReturnStatus ReadGlobalAttributeFromMetadata(DataModel::Provider * provider, const ConcreteAttributePath & path, + AttributeValueEncoder & encoder) +{ + CHIP_ERROR err; + + switch (path.mAttributeId) + { + case Clusters::Globals::Attributes::GeneratedCommandList::Id: { + DataModel::ListBuilder builder; + err = provider->GeneratedCommands(path, builder); + if (err != CHIP_NO_ERROR) + { + break; + } + auto buffer = builder.TakeBuffer(); + + return encoder.EncodeList([&buffer](const auto & listEncodeHelper) { + for (auto id : buffer) + { + // NOTE: cast to u64 because TLV encodes all numbers the same (no TLV sideffects) + // and this reduces template variants for Encode, saving flash. + ReturnErrorOnFailure(listEncodeHelper.Encode(static_cast(id))); + } + return CHIP_NO_ERROR; + }); + } + case Clusters::Globals::Attributes::AcceptedCommandList::Id: { + DataModel::ListBuilder builder; + err = provider->AcceptedCommands(path, builder); + if (err != CHIP_NO_ERROR) + { + break; + } + auto buffer = builder.TakeBuffer(); + + return encoder.EncodeList([&buffer](const auto & listEncodeHelper) { + for (auto entry : buffer) + { + // NOTE: cast to u64 because TLV encodes all numbers the same (no TLV sideffects) + // and this reduces template variants for Encode, saving flash. + ReturnErrorOnFailure(listEncodeHelper.Encode(static_cast(entry.commandId))); + } + return CHIP_NO_ERROR; + }); + } + case Clusters::Globals::Attributes::AttributeList::Id: { + DataModel::ListBuilder builder; + err = provider->Attributes(path, builder); + if (err != CHIP_NO_ERROR) + { + break; + } + auto buffer = builder.TakeBuffer(); + + return encoder.EncodeList([&buffer](const auto & listEncodeHelper) { + for (auto entry : buffer) + { + // NOTE: cast to u64 because TLV encodes all numbers the same (no TLV sideffects) + // and this reduces template variants for Encode, saving flash. + ReturnErrorOnFailure(listEncodeHelper.Encode(static_cast(entry.attributeId))); + } + + for (auto id : GlobalAttributesNotInMetadata) + { + // NOTE: cast to u64 because TLV encodes all numbers the same (no TLV sideffects) + // and this reduces template variants for Encode, saving flash. + ReturnErrorOnFailure(listEncodeHelper.Encode(static_cast(id))); + } + + return CHIP_NO_ERROR; + }); + } + default: + return CHIP_ERROR_INVALID_ARGUMENT; + } + + // if we get here, the path was NOT valid + if (err == CHIP_ERROR_NOT_FOUND) + { + // The `Failure` here is arbitrary: we expect ReadGlobalAttributeFromMetadata to be + // an internal API used for global attributes only and call preconditions say that + // should never happen. + // + // Code only takes this path if one of + // `GeneratedCommands`/`AcceptedCommands`/`Attribute` return a NOT_FOUND and + // that would indicate an invalid cluster (which should have been pre-validated by + // the caller). + return DataModel::ValidateClusterPath(provider, path, Status::Failure); + } + return err; +} + +} // namespace app +} // namespace chip diff --git a/src/app/GlobalAttributes.h b/src/app/GlobalAttributes.h index 7cfd06d3f7..e70674dbb0 100644 --- a/src/app/GlobalAttributes.h +++ b/src/app/GlobalAttributes.h @@ -19,6 +19,11 @@ #include #include +#include +#include +#include +#include +#include #include namespace chip { @@ -37,18 +42,17 @@ constexpr AttributeId GlobalAttributesNotInMetadata[] = { static_assert(ArrayIsSorted(GlobalAttributesNotInMetadata), "Array of global attribute ids must be sorted"); -inline bool IsSupportedGlobalAttributeNotInMetadata(AttributeId attributeId) -{ - for (auto & attr : GlobalAttributesNotInMetadata) - { - if (attr == attributeId) - { - return true; - } - } - - return false; -} +bool IsSupportedGlobalAttributeNotInMetadata(AttributeId attributeId); + +/** + * Reads a `IsSupportedGlobalAttributeNotInMetadata` attribute into `encoder`. + * + * Preconditions: + * - `path` MUST be a valid cluster path inside `provider` and its mAttributeID + * MUST be `IsSupportedGlobalAttributeNotInMetadata` + */ +DataModel::ActionReturnStatus ReadGlobalAttributeFromMetadata(DataModel::Provider * provider, const ConcreteAttributePath & path, + AttributeValueEncoder & encoder); } // namespace app } // namespace chip diff --git a/src/app/chip_data_model.cmake b/src/app/chip_data_model.cmake index dcafc0055d..65d3c0ada5 100644 --- a/src/app/chip_data_model.cmake +++ b/src/app/chip_data_model.cmake @@ -162,7 +162,6 @@ function(chip_configure_data_model APP_TARGET) ${CHIP_APP_BASE_DIR}/util/attribute-table.cpp ${CHIP_APP_BASE_DIR}/util/binding-table.cpp ${CHIP_APP_BASE_DIR}/util/DataModelHandler.cpp - ${CHIP_APP_BASE_DIR}/util/ember-global-attribute-access-interface.cpp ${CHIP_APP_BASE_DIR}/util/ember-io-storage.cpp ${CHIP_APP_BASE_DIR}/util/generic-callback-stubs.cpp ${CHIP_APP_BASE_DIR}/util/privilege-storage.cpp diff --git a/src/app/chip_data_model.gni b/src/app/chip_data_model.gni index 02be8ebacc..9dbe7ec193 100644 --- a/src/app/chip_data_model.gni +++ b/src/app/chip_data_model.gni @@ -209,7 +209,6 @@ template("chip_data_model") { "${_app_root}/util/DataModelHandler.cpp", "${_app_root}/util/attribute-storage.cpp", "${_app_root}/util/attribute-table.cpp", - "${_app_root}/util/ember-global-attribute-access-interface.cpp", "${_app_root}/util/ember-io-storage.cpp", "${_app_root}/util/util.cpp", ] diff --git a/src/app/data-model-provider/MetadataLookup.cpp b/src/app/data-model-provider/MetadataLookup.cpp index 5ec6b451ed..a249b7e33c 100644 --- a/src/app/data-model-provider/MetadataLookup.cpp +++ b/src/app/data-model-provider/MetadataLookup.cpp @@ -82,6 +82,27 @@ std::optional EndpointFinder::Find(EndpointId endpointId) return std::nullopt; } +Protocols::InteractionModel::Status ValidateClusterPath(ProviderMetadataTree * provider, const ConcreteClusterPath & path, + Protocols::InteractionModel::Status successStatus) +{ + if (ServerClusterFinder(provider).Find(path).has_value()) + { + return successStatus; + } + + auto endpoints = provider->EndpointsIgnoreError(); + for (auto & endpointEntry : endpoints) + { + if (endpointEntry.id == path.mEndpointId) + { + // endpoint is valid + return Protocols::InteractionModel::Status::UnsupportedCluster; + } + } + + return Protocols::InteractionModel::Status::UnsupportedEndpoint; +} + } // namespace DataModel } // namespace app } // namespace chip diff --git a/src/app/data-model-provider/MetadataLookup.h b/src/app/data-model-provider/MetadataLookup.h index 1d25122e7e..7526bd32ac 100644 --- a/src/app/data-model-provider/MetadataLookup.h +++ b/src/app/data-model-provider/MetadataLookup.h @@ -80,6 +80,14 @@ class EndpointFinder ReadOnlyBuffer mEndpoints; }; +/// Validates that the cluster identified by `path` exists within the given provider. +/// If the endpoint does not exist, will return Status::UnsupportedEndpoint. +/// If the endpoint exists but does not have the cluster identified by the path, will return Status::UnsupportedCluster. +/// +/// Otherwise, will return successStatus. +Protocols::InteractionModel::Status ValidateClusterPath(ProviderMetadataTree * provider, const ConcreteClusterPath & path, + Protocols::InteractionModel::Status successStatus); + } // namespace DataModel } // namespace app } // namespace chip diff --git a/src/app/data-model-provider/Provider.h b/src/app/data-model-provider/Provider.h index 3d0e2fec91..36a13d0eb8 100644 --- a/src/app/data-model-provider/Provider.h +++ b/src/app/data-model-provider/Provider.h @@ -58,8 +58,12 @@ class Provider : public ProviderMetadataTree // event emitting, path marking and other operations virtual InteractionModelContext CurrentContext() const { return mContext; } - /// TEMPORARY/TRANSITIONAL requirement for transitioning from ember-specific code - /// ReadAttribute is REQUIRED to respond to GlobalAttribute read requests + /// NOTE: this code is NOT required to handle `List` global attributes: + /// AcceptedCommandsList, GeneratedCommandsList OR AttributeList + /// + /// Users of DataModel::Provider are expected to get these lists + /// from ProviderMetadataTree (in particular IM Reads of these + /// attributes will the automatically filled from metadata). /// /// Return value notes: /// ActionReturnStatus::IsOutOfSpaceEncodingResponse diff --git a/src/app/data-model-provider/ProviderMetadataTree.h b/src/app/data-model-provider/ProviderMetadataTree.h index bad2e75336..3b0820e6ef 100644 --- a/src/app/data-model-provider/ProviderMetadataTree.h +++ b/src/app/data-model-provider/ProviderMetadataTree.h @@ -60,6 +60,14 @@ class ProviderMetadataTree virtual CHIP_ERROR ClientClusters(EndpointId endpointId, ListBuilder & builder) = 0; virtual CHIP_ERROR ServerClusters(EndpointId endpointId, ListBuilder & builder) = 0; + /// Attribute lists contain all attributes EXCEPT the list attributes that + /// are part of metadata. The output from this method MUST NOT contain: + /// - AttributeList::Id + /// - AcceptedCommandList::Id + /// - GeneratedCommandList::Id + /// However it MUST ALWAYS contain: + /// - ClusterRevision::Id + /// - FeatureMap::Id virtual CHIP_ERROR Attributes(const ConcreteClusterPath & path, ListBuilder & builder) = 0; virtual CHIP_ERROR GeneratedCommands(const ConcreteClusterPath & path, ListBuilder & builder) = 0; virtual CHIP_ERROR AcceptedCommands(const ConcreteClusterPath & path, ListBuilder & builder) = 0; diff --git a/src/app/data-model-provider/StringBuilderAdapters.cpp b/src/app/data-model-provider/StringBuilderAdapters.cpp index 5b8f6db5ea..69b697ac30 100644 --- a/src/app/data-model-provider/StringBuilderAdapters.cpp +++ b/src/app/data-model-provider/StringBuilderAdapters.cpp @@ -28,3 +28,15 @@ StatusWithSize ToString(const chip::ap } } // namespace pw +// +#if CHIP_CONFIG_TEST_GOOGLETEST +namespace chip { + +void PrintTo(const chip::app::DataModel::ActionReturnStatus & status, std::ostream * os) +{ + chip::app::DataModel::ActionReturnStatus::StringStorage storage; + *os << "ActionReturnStatus<" << status.c_str(storage) << ">"; +} + +} // namespace chip +#endif // CHIP_CONFIG_TEST_GOOGLETEST diff --git a/src/app/data-model-provider/StringBuilderAdapters.h b/src/app/data-model-provider/StringBuilderAdapters.h index 32da18f43f..e0649b9279 100644 --- a/src/app/data-model-provider/StringBuilderAdapters.h +++ b/src/app/data-model-provider/StringBuilderAdapters.h @@ -34,6 +34,7 @@ /// which is not as helpful as a full formatted output. #include +#include #include @@ -44,3 +45,11 @@ StatusWithSize ToString(const chip::ap pw::span buffer); } // namespace pw + +#if CHIP_CONFIG_TEST_GOOGLETEST +namespace chip { + +void PrintTo(const chip::app::DataModel::ActionReturnStatus & status, std::ostream * os); + +} // namespace chip +#endif // CHIP_CONFIG_TEST_GOOGLETEST diff --git a/src/app/reporting/Engine.cpp b/src/app/reporting/Engine.cpp index c9d6392286..fbcd9d302c 100644 --- a/src/app/reporting/Engine.cpp +++ b/src/app/reporting/Engine.cpp @@ -35,9 +35,10 @@ #include #include #include -#include #include +#include + #if CHIP_CONFIG_ENABLE_ICD_SERVER #include // nogncheck #endif @@ -173,10 +174,22 @@ DataModel::ActionReturnStatus RetrieveClusterData(DataModel::Provider * dataMode DataModel::ActionReturnStatus status(CHIP_NO_ERROR); AttributeValueEncoder attributeValueEncoder(reportBuilder, subjectDescriptor, path, version, isFabricFiltered, encoderState); + // TODO: we explicitly DO NOT validate that path is a valid cluster path (even more, above serverClusterFinder + // explicitly ignores that case). This means that global attribute reads as well as ReadAttribute + // can be passed invalid paths when an invalid Read is detected and must handle them. + // + // See https://github.com/project-chip/connectedhomeip/issues/37410 + if (auto access_status = ValidateReadAttributeACL(dataModel, subjectDescriptor, path); access_status.has_value()) { status = *access_status; } + else if (IsSupportedGlobalAttributeNotInMetadata(readRequest.path.mAttributeId)) + { + // Global attributes are NOT directly handled by data model providers, instead + // the are routed through metadata. + status = ReadGlobalAttributeFromMetadata(dataModel, readRequest.path, attributeValueEncoder); + } else { status = dataModel->ReadAttribute(readRequest, attributeValueEncoder); diff --git a/src/app/tests/TestReadInteraction.cpp b/src/app/tests/TestReadInteraction.cpp index b9313d896f..50b4b74529 100644 --- a/src/app/tests/TestReadInteraction.cpp +++ b/src/app/tests/TestReadInteraction.cpp @@ -1498,7 +1498,16 @@ void TestReadInteraction::TestReadWildcard() EXPECT_EQ(readClient.SendRequest(readPrepareParams), CHIP_NO_ERROR); DrainAndServiceIO(); - EXPECT_EQ(delegate.mNumAttributeResponse, 5); + // Expected attributes: + // - 0xFFFD Cluster revision + // - 0xFFFC Feature map + // - 0xFFF10001 + // - 0xFFF10002 + // - 0xFFF10003 + // - 0xFFF8 / GeneratedCommandList + // - 0xFFF9 / AcceptedCommandList + // - 0xFFFB / AttributeList + EXPECT_EQ(delegate.mNumAttributeResponse, 8); EXPECT_TRUE(delegate.mGotReport); EXPECT_FALSE(delegate.mReadError); // By now we should have closed all exchanges and sent all pending acks, so @@ -2814,17 +2823,17 @@ void TestReadInteraction::TestSubscribeWildcard() // Mock attribute storage that is reset and resides in src/app/util/mock/attribute-storage.cpp // has the following items: // - Endpoint 0xFFFE - // - cluster 0xFFF1'FC01 (2 attributes) - // - cluster 0xFFF1'FC02 (3 attributes) + // - cluster 0xFFF1'FC01 (2 attributes + 3 GlobalNotInMetadata) + // - cluster 0xFFF1'FC02 (3 attributes + 3 GlobalNotInMetadata) // - Endpoint 0xFFFD - // - cluster 0xFFF1'FC01 (2 attributes) - // - cluster 0xFFF1'FC02 (4 attributes) - // - cluster 0xFFF1'FC03 (5 attributes) + // - cluster 0xFFF1'FC01 (2 attributes + 3 GlobalNotInMetadata) + // - cluster 0xFFF1'FC02 (4 attributes + 3 GlobalNotInMetadata) + // - cluster 0xFFF1'FC03 (5 attributes + 3 GlobalNotInMetadata) // - Endpoint 0xFFFC - // - cluster 0xFFF1'FC01 (3 attributes) - // - cluster 0xFFF1'FC02 (6 attributes) - // - cluster 0xFFF1'FC03 (2 attributes) - // - cluster 0xFFF1'FC04 (2 attributes) + // - cluster 0xFFF1'FC01 (3 attributes + 3 GlobalNotInMetadata) + // - cluster 0xFFF1'FC02 (6 attributes + 3 GlobalNotInMetadata) + // - cluster 0xFFF1'FC03 (2 attributes + 3 GlobalNotInMetadata) + // - cluster 0xFFF1'FC04 (2 attributes + 3 GlobalNotInMetadata) // // // Actual chunk placement is execution defined, however generally @@ -2841,68 +2850,124 @@ void TestReadInteraction::TestSubscribeWildcard() constexpr AttributeCaptureAssertion kExpectedResponses[] = { AttributeCaptureAssertion(0xFFFE, 0xFFF1FC01, ClusterRevision::Id), AttributeCaptureAssertion(0xFFFE, 0xFFF1FC01, FeatureMap::Id), + AttributeCaptureAssertion(0xFFFE, 0xFFF1FC01, GeneratedCommandList::Id, /* listSize = */ 0), + AttributeCaptureAssertion(0xFFFE, 0xFFF1FC01, AcceptedCommandList::Id, /* listSize = */ 0), + AttributeCaptureAssertion(0xFFFE, 0xFFF1FC01, AttributeList::Id, /* listSize = */ 5), AttributeCaptureAssertion(0xFFFE, 0xFFF1FC02, ClusterRevision::Id), AttributeCaptureAssertion(0xFFFE, 0xFFF1FC02, FeatureMap::Id), AttributeCaptureAssertion(0xFFFE, 0xFFF1FC02, 0xFFF10001), + AttributeCaptureAssertion(0xFFFE, 0xFFF1FC02, GeneratedCommandList::Id, /* listSize = */ 0), + AttributeCaptureAssertion(0xFFFE, 0xFFF1FC02, AcceptedCommandList::Id, /* listSize = */ 0), + AttributeCaptureAssertion(0xFFFE, 0xFFF1FC02, AttributeList::Id, /* listSize = */ 6), AttributeCaptureAssertion(0xFFFD, 0xFFF1FC01, ClusterRevision::Id), AttributeCaptureAssertion(0xFFFD, 0xFFF1FC01, FeatureMap::Id), + AttributeCaptureAssertion(0xFFFD, 0xFFF1FC01, GeneratedCommandList::Id, /* listSize = */ 0), + AttributeCaptureAssertion(0xFFFD, 0xFFF1FC01, AcceptedCommandList::Id, /* listSize = */ 0), + AttributeCaptureAssertion(0xFFFD, 0xFFF1FC01, AttributeList::Id, /* listSize = */ 5), AttributeCaptureAssertion(0xFFFD, 0xFFF1FC02, ClusterRevision::Id), AttributeCaptureAssertion(0xFFFD, 0xFFF1FC02, FeatureMap::Id), AttributeCaptureAssertion(0xFFFD, 0xFFF1FC02, 0xFFF10001), AttributeCaptureAssertion(0xFFFD, 0xFFF1FC02, 0xFFF10002), + AttributeCaptureAssertion(0xFFFD, 0xFFF1FC02, GeneratedCommandList::Id, /* listSize = */ 0), + AttributeCaptureAssertion(0xFFFD, 0xFFF1FC02, AcceptedCommandList::Id, /* listSize = */ 0), + AttributeCaptureAssertion(0xFFFD, 0xFFF1FC02, AttributeList::Id, /* listSize = */ 7), AttributeCaptureAssertion(0xFFFD, 0xFFF1FC03, ClusterRevision::Id), AttributeCaptureAssertion(0xFFFD, 0xFFF1FC03, FeatureMap::Id), AttributeCaptureAssertion(0xFFFD, 0xFFF1FC03, 0xFFF10001), AttributeCaptureAssertion(0xFFFD, 0xFFF1FC03, 0xFFF10002), AttributeCaptureAssertion(0xFFFD, 0xFFF1FC03, 0xFFF10003), + AttributeCaptureAssertion(0xFFFD, 0xFFF1FC03, GeneratedCommandList::Id, /* listSize = */ 0), + AttributeCaptureAssertion(0xFFFD, 0xFFF1FC03, AcceptedCommandList::Id, /* listSize = */ 0), + AttributeCaptureAssertion(0xFFFD, 0xFFF1FC03, AttributeList::Id, /* listSize = */ 8), AttributeCaptureAssertion(0xFFFC, 0xFFF1FC01, ClusterRevision::Id), AttributeCaptureAssertion(0xFFFC, 0xFFF1FC01, FeatureMap::Id), AttributeCaptureAssertion(0xFFFC, 0xFFF1FC01, 0xFFF10001), + AttributeCaptureAssertion(0xFFFC, 0xFFF1FC01, GeneratedCommandList::Id, /* listSize = */ 0), + AttributeCaptureAssertion(0xFFFC, 0xFFF1FC01, AcceptedCommandList::Id, /* listSize = */ 0), + AttributeCaptureAssertion(0xFFFC, 0xFFF1FC01, AttributeList::Id, /* listSize = */ 6), AttributeCaptureAssertion(0xFFFC, 0xFFF1FC02, ClusterRevision::Id), AttributeCaptureAssertion(0xFFFC, 0xFFF1FC02, FeatureMap::Id), AttributeCaptureAssertion(0xFFFC, 0xFFF1FC02, 0xFFF10001), AttributeCaptureAssertion(0xFFFC, 0xFFF1FC02, 0xFFF10002), AttributeCaptureAssertion(0xFFFC, 0xFFF1FC02, 0xFFF10003), - AttributeCaptureAssertion(0xFFFC, 0xFFF1FC02, 0xFFF10004, /* listSize = */ 4), + AttributeCaptureAssertion(0xFFFC, 0xFFF1FC02, 0xFFF10004, /* listSize = */ 3), // Chunking here AttributeCaptureAssertion(0xFFFC, 0xFFF1FC02, 0xFFF10004, /* listSize = */ 1), AttributeCaptureAssertion(0xFFFC, 0xFFF1FC02, 0xFFF10004, /* listSize = */ 1), + AttributeCaptureAssertion(0xFFFC, 0xFFF1FC02, 0xFFF10004, /* listSize = */ 1), + AttributeCaptureAssertion(0xFFFC, 0xFFF1FC02, GeneratedCommandList::Id, /* listSize = */ 0), + AttributeCaptureAssertion(0xFFFC, 0xFFF1FC02, AcceptedCommandList::Id, /* listSize = */ 0), + AttributeCaptureAssertion(0xFFFC, 0xFFF1FC02, AttributeList::Id, /* listSize = */ 9), AttributeCaptureAssertion(0xFFFC, 0xFFF1FC03, ClusterRevision::Id), AttributeCaptureAssertion(0xFFFC, 0xFFF1FC03, FeatureMap::Id), + AttributeCaptureAssertion(0xFFFC, 0xFFF1FC03, GeneratedCommandList::Id, /* listSize = */ 0), + AttributeCaptureAssertion(0xFFFC, 0xFFF1FC03, AcceptedCommandList::Id, /* listSize = */ 0), + AttributeCaptureAssertion(0xFFFC, 0xFFF1FC03, AttributeList::Id, /* listSize = */ 5), AttributeCaptureAssertion(0xFFFC, 0xFFF1FC04, ClusterRevision::Id), AttributeCaptureAssertion(0xFFFC, 0xFFF1FC04, FeatureMap::Id), + AttributeCaptureAssertion(0xFFFC, 0xFFF1FC04, GeneratedCommandList::Id, /* listSize = */ 0), + AttributeCaptureAssertion(0xFFFC, 0xFFF1FC04, AcceptedCommandList::Id, /* listSize = */ 0), + AttributeCaptureAssertion(0xFFFC, 0xFFF1FC04, AttributeList::Id, /* listSize = */ 5), AttributeCaptureAssertion(0xFFFE, 0xFFF1FC01, ClusterRevision::Id), AttributeCaptureAssertion(0xFFFE, 0xFFF1FC01, FeatureMap::Id), + AttributeCaptureAssertion(0xFFFE, 0xFFF1FC01, GeneratedCommandList::Id, /* listSize = */ 0), + AttributeCaptureAssertion(0xFFFE, 0xFFF1FC01, AcceptedCommandList::Id, /* listSize = */ 0), + AttributeCaptureAssertion(0xFFFE, 0xFFF1FC01, AttributeList::Id, /* listSize = */ 5), AttributeCaptureAssertion(0xFFFE, 0xFFF1FC02, ClusterRevision::Id), AttributeCaptureAssertion(0xFFFE, 0xFFF1FC02, FeatureMap::Id), AttributeCaptureAssertion(0xFFFE, 0xFFF1FC02, 0xFFF10001), + AttributeCaptureAssertion(0xFFFE, 0xFFF1FC02, GeneratedCommandList::Id, /* listSize = */ 0), + AttributeCaptureAssertion(0xFFFE, 0xFFF1FC02, AcceptedCommandList::Id, /* listSize = */ 0), + AttributeCaptureAssertion(0xFFFE, 0xFFF1FC02, AttributeList::Id, /* listSize = */ 6), AttributeCaptureAssertion(0xFFFD, 0xFFF1FC01, ClusterRevision::Id), AttributeCaptureAssertion(0xFFFD, 0xFFF1FC01, FeatureMap::Id), + AttributeCaptureAssertion(0xFFFD, 0xFFF1FC01, GeneratedCommandList::Id, /* listSize = */ 0), + AttributeCaptureAssertion(0xFFFD, 0xFFF1FC01, AcceptedCommandList::Id, /* listSize = */ 0), + AttributeCaptureAssertion(0xFFFD, 0xFFF1FC01, AttributeList::Id, /* listSize = */ 5), AttributeCaptureAssertion(0xFFFD, 0xFFF1FC02, ClusterRevision::Id), AttributeCaptureAssertion(0xFFFD, 0xFFF1FC02, FeatureMap::Id), AttributeCaptureAssertion(0xFFFD, 0xFFF1FC02, 0xFFF10001), AttributeCaptureAssertion(0xFFFD, 0xFFF1FC02, 0xFFF10002), + AttributeCaptureAssertion(0xFFFD, 0xFFF1FC02, GeneratedCommandList::Id, /* listSize = */ 0), + AttributeCaptureAssertion(0xFFFD, 0xFFF1FC02, AcceptedCommandList::Id, /* listSize = */ 0), + AttributeCaptureAssertion(0xFFFD, 0xFFF1FC02, AttributeList::Id, /* listSize = */ 7), AttributeCaptureAssertion(0xFFFD, 0xFFF1FC03, ClusterRevision::Id), AttributeCaptureAssertion(0xFFFD, 0xFFF1FC03, FeatureMap::Id), AttributeCaptureAssertion(0xFFFD, 0xFFF1FC03, 0xFFF10001), AttributeCaptureAssertion(0xFFFD, 0xFFF1FC03, 0xFFF10002), AttributeCaptureAssertion(0xFFFD, 0xFFF1FC03, 0xFFF10003), + AttributeCaptureAssertion(0xFFFD, 0xFFF1FC03, GeneratedCommandList::Id, /* listSize = */ 0), + AttributeCaptureAssertion(0xFFFD, 0xFFF1FC03, AcceptedCommandList::Id, /* listSize = */ 0), + AttributeCaptureAssertion(0xFFFD, 0xFFF1FC03, AttributeList::Id, /* listSize = */ 8), AttributeCaptureAssertion(0xFFFC, 0xFFF1FC01, ClusterRevision::Id), AttributeCaptureAssertion(0xFFFC, 0xFFF1FC01, FeatureMap::Id), AttributeCaptureAssertion(0xFFFC, 0xFFF1FC01, 0xFFF10001), + AttributeCaptureAssertion(0xFFFC, 0xFFF1FC01, GeneratedCommandList::Id, /* listSize = */ 0), + AttributeCaptureAssertion(0xFFFC, 0xFFF1FC01, AcceptedCommandList::Id, /* listSize = */ 0), + AttributeCaptureAssertion(0xFFFC, 0xFFF1FC01, AttributeList::Id, /* listSize = */ 6), AttributeCaptureAssertion(0xFFFC, 0xFFF1FC02, ClusterRevision::Id), AttributeCaptureAssertion(0xFFFC, 0xFFF1FC02, FeatureMap::Id), AttributeCaptureAssertion(0xFFFC, 0xFFF1FC02, 0xFFF10001), AttributeCaptureAssertion(0xFFFC, 0xFFF1FC02, 0xFFF10002), AttributeCaptureAssertion(0xFFFC, 0xFFF1FC02, 0xFFF10003), - AttributeCaptureAssertion(0xFFFC, 0xFFF1FC02, 0xFFF10004, /* listSize = */ 4), + AttributeCaptureAssertion(0xFFFC, 0xFFF1FC02, 0xFFF10004, /* listSize = */ 3), // Chunking here AttributeCaptureAssertion(0xFFFC, 0xFFF1FC02, 0xFFF10004, /* listSize = */ 1), AttributeCaptureAssertion(0xFFFC, 0xFFF1FC02, 0xFFF10004, /* listSize = */ 1), + AttributeCaptureAssertion(0xFFFC, 0xFFF1FC02, 0xFFF10004, /* listSize = */ 1), + AttributeCaptureAssertion(0xFFFC, 0xFFF1FC02, GeneratedCommandList::Id, /* listSize = */ 0), + AttributeCaptureAssertion(0xFFFC, 0xFFF1FC02, AcceptedCommandList::Id, /* listSize = */ 0), + AttributeCaptureAssertion(0xFFFC, 0xFFF1FC02, AttributeList::Id, /* listSize = */ 9), AttributeCaptureAssertion(0xFFFC, 0xFFF1FC03, ClusterRevision::Id), AttributeCaptureAssertion(0xFFFC, 0xFFF1FC03, FeatureMap::Id), + AttributeCaptureAssertion(0xFFFC, 0xFFF1FC03, GeneratedCommandList::Id, /* listSize = */ 0), + AttributeCaptureAssertion(0xFFFC, 0xFFF1FC03, AcceptedCommandList::Id, /* listSize = */ 0), + AttributeCaptureAssertion(0xFFFC, 0xFFF1FC03, AttributeList::Id, /* listSize = */ 5), AttributeCaptureAssertion(0xFFFC, 0xFFF1FC04, ClusterRevision::Id), AttributeCaptureAssertion(0xFFFC, 0xFFF1FC04, FeatureMap::Id), + AttributeCaptureAssertion(0xFFFC, 0xFFF1FC04, GeneratedCommandList::Id, /* listSize = */ 0), + AttributeCaptureAssertion(0xFFFC, 0xFFF1FC04, AcceptedCommandList::Id, /* listSize = */ 0), + AttributeCaptureAssertion(0xFFFC, 0xFFF1FC04, AttributeList::Id, /* listSize = */ 5), }; ASSERT_TRUE(delegate.CapturesMatchExactly(chip::Span(kExpectedResponses))); @@ -2956,6 +3021,9 @@ void TestReadInteraction::TestSubscribeWildcard() AttributeCaptureAssertion(0xFFFC, 0xFFF1FC01, ClusterRevision::Id), AttributeCaptureAssertion(0xFFFC, 0xFFF1FC01, FeatureMap::Id), AttributeCaptureAssertion(0xFFFC, 0xFFF1FC01, 0xFFF10001), + AttributeCaptureAssertion(0xFFFC, 0xFFF1FC01, GeneratedCommandList::Id, /* listSize = */ 0), + AttributeCaptureAssertion(0xFFFC, 0xFFF1FC01, AcceptedCommandList::Id, /* listSize = */ 0), + AttributeCaptureAssertion(0xFFFC, 0xFFF1FC01, AttributeList::Id, /* listSize = */ 6), AttributeCaptureAssertion(0xFFFC, 0xFFF1FC02, ClusterRevision::Id), AttributeCaptureAssertion(0xFFFC, 0xFFF1FC02, FeatureMap::Id), AttributeCaptureAssertion(0xFFFC, 0xFFF1FC02, 0xFFF10001), @@ -2965,13 +3033,25 @@ void TestReadInteraction::TestSubscribeWildcard() AttributeCaptureAssertion(0xFFFC, 0xFFF1FC02, 0xFFF10004, /* listSize = */ 1), AttributeCaptureAssertion(0xFFFC, 0xFFF1FC02, 0xFFF10004, /* listSize = */ 1), AttributeCaptureAssertion(0xFFFC, 0xFFF1FC02, 0xFFF10004, /* listSize = */ 1), + AttributeCaptureAssertion(0xFFFC, 0xFFF1FC02, GeneratedCommandList::Id, /* listSize = */ 0), + AttributeCaptureAssertion(0xFFFC, 0xFFF1FC02, AcceptedCommandList::Id, /* listSize = */ 0), + AttributeCaptureAssertion(0xFFFC, 0xFFF1FC02, AttributeList::Id, /* listSize = */ 9), AttributeCaptureAssertion(0xFFFC, 0xFFF1FC03, ClusterRevision::Id), AttributeCaptureAssertion(0xFFFC, 0xFFF1FC03, FeatureMap::Id), + AttributeCaptureAssertion(0xFFFC, 0xFFF1FC03, GeneratedCommandList::Id, /* listSize = */ 0), + AttributeCaptureAssertion(0xFFFC, 0xFFF1FC03, AcceptedCommandList::Id, /* listSize = */ 0), + AttributeCaptureAssertion(0xFFFC, 0xFFF1FC03, AttributeList::Id, /* listSize = */ 5), AttributeCaptureAssertion(0xFFFC, 0xFFF1FC04, ClusterRevision::Id), AttributeCaptureAssertion(0xFFFC, 0xFFF1FC04, FeatureMap::Id), + AttributeCaptureAssertion(0xFFFC, 0xFFF1FC04, GeneratedCommandList::Id, /* listSize = */ 0), + AttributeCaptureAssertion(0xFFFC, 0xFFF1FC04, AcceptedCommandList::Id, /* listSize = */ 0), + AttributeCaptureAssertion(0xFFFC, 0xFFF1FC04, AttributeList::Id, /* listSize = */ 5), AttributeCaptureAssertion(0xFFFC, 0xFFF1FC01, ClusterRevision::Id), AttributeCaptureAssertion(0xFFFC, 0xFFF1FC01, FeatureMap::Id), AttributeCaptureAssertion(0xFFFC, 0xFFF1FC01, 0xFFF10001), + AttributeCaptureAssertion(0xFFFC, 0xFFF1FC01, GeneratedCommandList::Id, /* listSize = */ 0), + AttributeCaptureAssertion(0xFFFC, 0xFFF1FC01, AcceptedCommandList::Id, /* listSize = */ 0), + AttributeCaptureAssertion(0xFFFC, 0xFFF1FC01, AttributeList::Id, /* listSize = */ 6), AttributeCaptureAssertion(0xFFFC, 0xFFF1FC02, ClusterRevision::Id), AttributeCaptureAssertion(0xFFFC, 0xFFF1FC02, FeatureMap::Id), AttributeCaptureAssertion(0xFFFC, 0xFFF1FC02, 0xFFF10001), @@ -2982,10 +3062,19 @@ void TestReadInteraction::TestSubscribeWildcard() AttributeCaptureAssertion(0xFFFC, 0xFFF1FC02, 0xFFF10004, /* listSize = */ 1), AttributeCaptureAssertion(0xFFFC, 0xFFF1FC02, 0xFFF10004, /* listSize = */ 1), AttributeCaptureAssertion(0xFFFC, 0xFFF1FC02, 0xFFF10004, /* listSize = */ 1), + AttributeCaptureAssertion(0xFFFC, 0xFFF1FC02, GeneratedCommandList::Id, /* listSize = */ 0), + AttributeCaptureAssertion(0xFFFC, 0xFFF1FC02, AcceptedCommandList::Id, /* listSize = */ 0), + AttributeCaptureAssertion(0xFFFC, 0xFFF1FC02, AttributeList::Id, /* listSize = */ 9), AttributeCaptureAssertion(0xFFFC, 0xFFF1FC03, ClusterRevision::Id), AttributeCaptureAssertion(0xFFFC, 0xFFF1FC03, FeatureMap::Id), + AttributeCaptureAssertion(0xFFFC, 0xFFF1FC03, GeneratedCommandList::Id, /* listSize = */ 0), + AttributeCaptureAssertion(0xFFFC, 0xFFF1FC03, AcceptedCommandList::Id, /* listSize = */ 0), + AttributeCaptureAssertion(0xFFFC, 0xFFF1FC03, AttributeList::Id, /* listSize = */ 5), AttributeCaptureAssertion(0xFFFC, 0xFFF1FC04, ClusterRevision::Id), AttributeCaptureAssertion(0xFFFC, 0xFFF1FC04, FeatureMap::Id), + AttributeCaptureAssertion(0xFFFC, 0xFFF1FC04, GeneratedCommandList::Id, /* listSize = */ 0), + AttributeCaptureAssertion(0xFFFC, 0xFFF1FC04, AcceptedCommandList::Id, /* listSize = */ 0), + AttributeCaptureAssertion(0xFFFC, 0xFFF1FC04, AttributeList::Id, /* listSize = */ 5), }; diff --git a/src/app/tests/suites/TestBasicInformation.yaml b/src/app/tests/suites/TestBasicInformation.yaml index f07e3c3fd7..1240947423 100644 --- a/src/app/tests/suites/TestBasicInformation.yaml +++ b/src/app/tests/suites/TestBasicInformation.yaml @@ -57,71 +57,75 @@ tests: command: "readAttribute" attribute: "AttributeList" response: - value: [ - 0, - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 18, - 19, - 20, - 21, - 22, - 0xFFF8, # GeneratedCommandList - 0xFFF9, # AcceptedCommandList - 0xFFFA, # EventList - 0xFFFB, # AttributeList - 0xFFFC, # FeatureMap - 0xFFFD, # ClusterRevision - ] + constraints: + python: | + return set(value) == { + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 18, + 19, + 20, + 21, + 22, + 0xFFF8, # GeneratedCommandList + 0xFFF9, # AcceptedCommandList + 0xFFFA, # EventList + 0xFFFB, # AttributeList + 0xFFFC, # FeatureMap + 0xFFFD, # ClusterRevision + } - label: "Read AttributeList value" PICS: "!PICS_EVENT_LIST_ENABLED" command: "readAttribute" attribute: "AttributeList" response: - value: [ - 0, - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 18, - 19, - 20, - 21, - 22, - 0xFFF8, # GeneratedCommandList - 0xFFF9, # AcceptedCommandList - 0xFFFB, # AttributeList - 0xFFFC, # FeatureMap - 0xFFFD, # ClusterRevision - ] + constraints: + python: | + return set(value) == { + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 18, + 19, + 20, + 21, + 22, + 0xFFF8, # GeneratedCommandList + 0xFFF9, # AcceptedCommandList + 0xFFFB, # AttributeList + 0xFFFC, # FeatureMap + 0xFFFD, # ClusterRevision + } - label: "Read NodeLabel" command: "readAttribute" diff --git a/src/app/util/ember-global-attribute-access-interface.cpp b/src/app/util/ember-global-attribute-access-interface.cpp deleted file mode 100644 index 9878f41d45..0000000000 --- a/src/app/util/ember-global-attribute-access-interface.cpp +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (c) 2021-2024 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. - */ -#include - -#include -#include -#include - -namespace chip { -namespace app { -namespace Compatibility { - -CHIP_ERROR GlobalAttributeReader::Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) -{ - using namespace Clusters::Globals::Attributes; - switch (aPath.mAttributeId) - { - case AttributeList::Id: - return aEncoder.EncodeList([this](const auto & encoder) { - const size_t count = mCluster->attributeCount; - bool addedExtraGlobals = false; - for (size_t i = 0; i < count; ++i) - { - AttributeId id = mCluster->attributes[i].attributeId; - constexpr auto lastGlobalId = GlobalAttributesNotInMetadata[ArraySize(GlobalAttributesNotInMetadata) - 1]; - // If EventList is not supported. The GlobalAttributesNotInMetadata is missing one id here. - static_assert(lastGlobalId - GlobalAttributesNotInMetadata[0] == ArraySize(GlobalAttributesNotInMetadata), - "Ids in GlobalAttributesNotInMetadata not consecutive (except EventList)"); - if (!addedExtraGlobals && id > lastGlobalId) - { - for (const auto & globalId : GlobalAttributesNotInMetadata) - { - ReturnErrorOnFailure(encoder.Encode(globalId)); - } - addedExtraGlobals = true; - } - ReturnErrorOnFailure(encoder.Encode(id)); - } - if (!addedExtraGlobals) - { - for (const auto & globalId : GlobalAttributesNotInMetadata) - { - ReturnErrorOnFailure(encoder.Encode(globalId)); - } - } - return CHIP_NO_ERROR; - }); - case AcceptedCommandList::Id: - return EncodeCommandList(aPath, aEncoder, &CommandHandlerInterface::EnumerateAcceptedCommands, - mCluster->acceptedCommandList); - case GeneratedCommandList::Id: - return EncodeCommandList(aPath, aEncoder, &CommandHandlerInterface::EnumerateGeneratedCommands, - mCluster->generatedCommandList); - default: - // This function is only called if attributeCluster is non-null in - // ReadSingleClusterData, which only happens for attributes listed in - // GlobalAttributesNotInMetadata. If we reach this code, someone added - // a global attribute to that list but not the above switch. - VerifyOrDieWithMsg(false, DataManagement, "Unexpected global attribute: " ChipLogFormatMEI, - ChipLogValueMEI(aPath.mAttributeId)); - return CHIP_NO_ERROR; - } -} - -CHIP_ERROR GlobalAttributeReader::EncodeCommandList(const ConcreteClusterPath & aClusterPath, AttributeValueEncoder & aEncoder, - GlobalAttributeReader::CommandListEnumerator aEnumerator, - const CommandId * aClusterCommandList) -{ - return aEncoder.EncodeList([&](const auto & encoder) { - auto * commandHandler = - CommandHandlerInterfaceRegistry::Instance().GetCommandHandler(aClusterPath.mEndpointId, aClusterPath.mClusterId); - if (commandHandler) - { - struct Context - { - decltype(encoder) & commandIdEncoder; - CHIP_ERROR err; - } context{ encoder, CHIP_NO_ERROR }; - CHIP_ERROR err = (commandHandler->*aEnumerator)( - aClusterPath, - [](CommandId command, void * closure) -> Loop { - auto * ctx = static_cast(closure); - ctx->err = ctx->commandIdEncoder.Encode(command); - if (ctx->err != CHIP_NO_ERROR) - { - return Loop::Break; - } - return Loop::Continue; - }, - &context); - if (err != CHIP_ERROR_NOT_IMPLEMENTED) - { - return context.err; - } - // Else fall through to the list in aClusterCommandList. - } - - for (const CommandId * cmd = aClusterCommandList; cmd != nullptr && *cmd != kInvalidCommandId; cmd++) - { - ReturnErrorOnFailure(encoder.Encode(*cmd)); - } - return CHIP_NO_ERROR; - }); -} - -} // namespace Compatibility -} // namespace app -} // namespace chip diff --git a/src/app/util/ember-global-attribute-access-interface.h b/src/app/util/ember-global-attribute-access-interface.h deleted file mode 100644 index d17e1b286d..0000000000 --- a/src/app/util/ember-global-attribute-access-interface.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2021-2024 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. - */ -#pragma once - -#include -#include -#include - -namespace chip { -namespace app { -namespace Compatibility { - -// This reader should never actually be registered; we do manual dispatch to it -// for the one attribute it handles. -class MandatoryGlobalAttributeReader : public AttributeAccessInterface -{ -public: - MandatoryGlobalAttributeReader(const EmberAfCluster * aCluster) : - AttributeAccessInterface(MakeOptional(kInvalidEndpointId), kInvalidClusterId), mCluster(aCluster) - {} - -protected: - const EmberAfCluster * mCluster; -}; - -class GlobalAttributeReader : public MandatoryGlobalAttributeReader -{ -public: - GlobalAttributeReader(const EmberAfCluster * aCluster) : MandatoryGlobalAttributeReader(aCluster) {} - - CHIP_ERROR Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) override; - -private: - typedef CHIP_ERROR (CommandHandlerInterface::*CommandListEnumerator)(const ConcreteClusterPath & cluster, - CommandHandlerInterface::CommandIdCallback callback, - void * context); - static CHIP_ERROR EncodeCommandList(const ConcreteClusterPath & aClusterPath, AttributeValueEncoder & aEncoder, - CommandListEnumerator aEnumerator, const CommandId * aClusterCommandList); -}; - -} // namespace Compatibility -} // namespace app -} // namespace chip diff --git a/src/app/util/mock/BUILD.gn b/src/app/util/mock/BUILD.gn index 5147b447f2..c7fd8cc480 100644 --- a/src/app/util/mock/BUILD.gn +++ b/src/app/util/mock/BUILD.gn @@ -49,7 +49,6 @@ source_set("mock_codegen_data_model") { public_deps = codegen_data_model_PUBLIC_DEPS sources += [ - "${chip_root}/src/app/util/ember-global-attribute-access-interface.cpp", "${chip_root}/src/app/util/ember-io-storage.cpp", "CodegenEmberMocks.cpp", ] diff --git a/src/controller/tests/data_model/TestRead.cpp b/src/controller/tests/data_model/TestRead.cpp index f423675c66..d320def488 100644 --- a/src/controller/tests/data_model/TestRead.cpp +++ b/src/controller/tests/data_model/TestRead.cpp @@ -290,8 +290,8 @@ TEST_F(TestRead, TestReadSubscribeAttributeResponseWithVersionOnlyCache) EXPECT_EQ(err, CHIP_NO_ERROR); DrainAndServiceIO(); - // There are supported 2 global and 3 non-global attributes in E2C2A* and 1 E3C2A2 - EXPECT_EQ(delegate.mNumAttributeResponse, 6); + // There are supported 5 global and 3 non-global attributes in E2C2A* and 1 E3C2A2 + EXPECT_EQ(delegate.mNumAttributeResponse, 9); EXPECT_FALSE(delegate.mReadError); Optional version1; ConcreteClusterPath clusterPath1(kMockEndpoint2, MockClusterId(3)); @@ -374,7 +374,7 @@ TEST_F(TestRead, TestReadSubscribeAttributeResponseWithCache) EXPECT_EQ(err, CHIP_NO_ERROR); DrainAndServiceIO(); - EXPECT_EQ(delegate.mNumAttributeResponse, 6); + EXPECT_EQ(delegate.mNumAttributeResponse, 9); EXPECT_FALSE(delegate.mReadError); Optional version1; ConcreteClusterPath clusterPath1(kMockEndpoint2, MockClusterId(3)); @@ -535,8 +535,8 @@ TEST_F(TestRead, TestReadSubscribeAttributeResponseWithCache) EXPECT_EQ(err, CHIP_NO_ERROR); DrainAndServiceIO(); - // There are supported 2 global and 3 non-global attributes in E2C2A* and 1 E3C2A2 - EXPECT_EQ(delegate.mNumAttributeResponse, 6); + // There are supported 5 global and 3 non-global attributes in E2C2A* and 1 E3C2A2 + EXPECT_EQ(delegate.mNumAttributeResponse, 9); EXPECT_FALSE(delegate.mReadError); Optional version1; ConcreteClusterPath clusterPath1(kMockEndpoint2, MockClusterId(3)); @@ -877,7 +877,7 @@ TEST_F(TestRead, TestReadSubscribeAttributeResponseWithCache) EXPECT_EQ(err, CHIP_NO_ERROR); DrainAndServiceIO(); - EXPECT_EQ(delegate.mNumAttributeResponse, 6); + EXPECT_EQ(delegate.mNumAttributeResponse, 9); EXPECT_FALSE(delegate.mReadError); Optional version1; ConcreteClusterPath clusterPath1(kMockEndpoint2, MockClusterId(3)); @@ -956,7 +956,7 @@ TEST_F(TestRead, TestReadSubscribeAttributeResponseWithCache) EXPECT_EQ(err, CHIP_NO_ERROR); DrainAndServiceIO(); - EXPECT_EQ(delegate.mNumAttributeResponse, 6); + EXPECT_EQ(delegate.mNumAttributeResponse, 9); EXPECT_FALSE(delegate.mReadError); Optional version1; ConcreteClusterPath clusterPath1(kMockEndpoint2, MockClusterId(3)); @@ -1037,7 +1037,8 @@ TEST_F(TestRead, TestReadSubscribeAttributeResponseWithCache) DrainAndServiceIO(); // E1C2A* has 3 attributes and E2C3A* has 5 attributes and E2C2A* has 4 attributes - EXPECT_EQ(delegate.mNumAttributeResponse, 12); + // + 3 global attributes not in metadata (3*3 = 9) for attributes/acceptedcommands/generatedcommands + EXPECT_EQ(delegate.mNumAttributeResponse, 21); EXPECT_FALSE(delegate.mReadError); Optional version1; ConcreteClusterPath clusterPath1(kMockEndpoint2, MockClusterId(3)); @@ -1142,7 +1143,7 @@ TEST_F(TestRead, TestReadSubscribeAttributeResponseWithCache) EXPECT_EQ(err, CHIP_NO_ERROR); DrainAndServiceIO(); - EXPECT_EQ(delegate.mNumAttributeResponse, 7); + EXPECT_EQ(delegate.mNumAttributeResponse, 13); EXPECT_FALSE(delegate.mReadError); Optional version1; ConcreteClusterPath clusterPath1(kMockEndpoint2, MockClusterId(3)); @@ -1232,7 +1233,7 @@ TEST_F(TestRead, TestReadSubscribeAttributeResponseWithCache) EXPECT_EQ(err, CHIP_NO_ERROR); DrainAndServiceIO(); - EXPECT_EQ(delegate.mNumAttributeResponse, 6); + EXPECT_EQ(delegate.mNumAttributeResponse, 9); EXPECT_FALSE(delegate.mReadError); Optional version1; ConcreteClusterPath clusterPath(kMockEndpoint3, MockClusterId(2)); diff --git a/src/darwin/Framework/CHIPTests/MTRPerControllerStorageTests.m b/src/darwin/Framework/CHIPTests/MTRPerControllerStorageTests.m index 779b42abdf..ca733c0b2f 100644 --- a/src/darwin/Framework/CHIPTests/MTRPerControllerStorageTests.m +++ b/src/darwin/Framework/CHIPTests/MTRPerControllerStorageTests.m @@ -2585,7 +2585,7 @@ - (void)testControllerServer @{ MTRAttributePathKey : globalAttributePath(clusterId1, MTRAttributeIDTypeGlobalAttributeAttributeListID), MTRDataKey : arrayOfUnsignedIntegersValue(@[ - attributeId1, @(0xFFF8), @(0xFFF9), @(0xFFFB), attributeId2, @(0xFFFC), @(0xFFFD) + attributeId1, attributeId2, @(0xFFFC), @(0xFFFD), @(0xFFF8), @(0xFFF9), @(0xFFFB) ]), }, @@ -2612,7 +2612,7 @@ - (void)testControllerServer @{ MTRAttributePathKey : globalAttributePath(clusterId2, MTRAttributeIDTypeGlobalAttributeAttributeListID), MTRDataKey : arrayOfUnsignedIntegersValue(@[ - @0xFFF8, @(0xFFF9), @(0xFFFB), attributeId2, @(0xFFFC), @(0xFFFD) + attributeId2, @(0xFFFC), @(0xFFFD), @0xFFF8, @(0xFFF9), @(0xFFFB) ]), }, @@ -2655,7 +2655,7 @@ - (void)testControllerServer @{ MTRAttributePathKey : globalAttributePath(@(MTRClusterIDTypeDescriptorID), MTRAttributeIDTypeGlobalAttributeAttributeListID), MTRDataKey : arrayOfUnsignedIntegersValue(@[ - @(0), @(1), @(2), @(3), @(0xFFF8), @(0xFFF9), @(0xFFFB), @(0xFFFC), @(0xFFFD) + @(0), @(1), @(2), @(3), @(0xFFFC), @(0xFFFD), @(0xFFF8), @(0xFFF9), @(0xFFFB) ]), }, diff --git a/src/darwin/Framework/Matter.xcodeproj/project.pbxproj b/src/darwin/Framework/Matter.xcodeproj/project.pbxproj index c6f16a3920..2fd209207e 100644 --- a/src/darwin/Framework/Matter.xcodeproj/project.pbxproj +++ b/src/darwin/Framework/Matter.xcodeproj/project.pbxproj @@ -464,8 +464,6 @@ D4772A46285AE98400383630 /* MTRClusterConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = D4772A45285AE98300383630 /* MTRClusterConstants.h */; settings = {ATTRIBUTES = (Public, ); }; }; E04AC67D2BEEA17F00BA409B /* ember-io-storage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E04AC67B2BEEA17F00BA409B /* ember-io-storage.cpp */; }; E04AC67E2BEEA17F00BA409B /* ember-io-storage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E04AC67B2BEEA17F00BA409B /* ember-io-storage.cpp */; }; - E04AC67F2BEEA17F00BA409B /* ember-global-attribute-access-interface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E04AC67C2BEEA17F00BA409B /* ember-global-attribute-access-interface.cpp */; }; - E04AC6802BEEA17F00BA409B /* ember-global-attribute-access-interface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E04AC67C2BEEA17F00BA409B /* ember-global-attribute-access-interface.cpp */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -978,7 +976,6 @@ D444F9A82C6E99CA007761E5 /* MTRXPCClientProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MTRXPCClientProtocol.h; sourceTree = ""; }; D4772A45285AE98300383630 /* MTRClusterConstants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MTRClusterConstants.h; sourceTree = ""; }; E04AC67B2BEEA17F00BA409B /* ember-io-storage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "ember-io-storage.cpp"; path = "util/ember-io-storage.cpp"; sourceTree = ""; }; - E04AC67C2BEEA17F00BA409B /* ember-global-attribute-access-interface.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "ember-global-attribute-access-interface.cpp"; path = "util/ember-global-attribute-access-interface.cpp"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -1239,7 +1236,6 @@ 5143041F2914CED9004DC7FE /* generic-callback-stubs.cpp */, 514C79F22B62ED5500DD6D7B /* attribute-storage.cpp */, 514C79EF2B62ADDA00DD6D7B /* descriptor.cpp */, - E04AC67C2BEEA17F00BA409B /* ember-global-attribute-access-interface.cpp */, E04AC67B2BEEA17F00BA409B /* ember-io-storage.cpp */, 516415FE2B6B132200D5CE11 /* DataModelHandler.cpp */, 514C79F52B62F0B900DD6D7B /* util.cpp */, @@ -2307,7 +2303,6 @@ 037C3DB62991BD5000B7EEE2 /* ModelCommandBridge.mm in Sources */, 516411322B6BF75700E67C05 /* MTRIMDispatch.mm in Sources */, 037C3DB42991BD5000B7EEE2 /* DeviceControllerDelegateBridge.mm in Sources */, - E04AC6802BEEA17F00BA409B /* ember-global-attribute-access-interface.cpp in Sources */, 039547012992D461006D42A8 /* generic-callback-stubs.cpp in Sources */, 514C79F12B62ADDA00DD6D7B /* descriptor.cpp in Sources */, ); @@ -2408,7 +2403,6 @@ 5178E67E2AE098210069DF72 /* MTRCommandTimedCheck.mm in Sources */, 7596A84928762783004DAE0E /* MTRAsyncCallbackWorkQueue.mm in Sources */, B2E0D7B9245B0B5C003C5B48 /* MTRSetupPayload.mm in Sources */, - E04AC67F2BEEA17F00BA409B /* ember-global-attribute-access-interface.cpp in Sources */, B2E0D7B6245B0B5C003C5B48 /* MTRManualSetupPayloadParser.mm in Sources */, 7596A85528788557004DAE0E /* MTRClusters.mm in Sources */, 88EBF8CF27FABDD500686BC1 /* MTRDeviceAttestationDelegateBridge.mm in Sources */, diff --git a/src/data-model-providers/codegen/CodegenDataModelProvider_Read.cpp b/src/data-model-providers/codegen/CodegenDataModelProvider_Read.cpp index 2c2ed3102e..59c14474c2 100644 --- a/src/data-model-providers/codegen/CodegenDataModelProvider_Read.cpp +++ b/src/data-model-providers/codegen/CodegenDataModelProvider_Read.cpp @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include @@ -34,7 +33,6 @@ #include #include #include -#include #include #include #include @@ -116,27 +114,13 @@ DataModel::ActionReturnStatus CodegenDataModelProvider::ReadAttribute(const Data } // Read via AAI - std::optional aai_result; - if (const EmberAfCluster ** cluster = std::get_if(&metadata)) - { - Compatibility::GlobalAttributeReader aai(*cluster); - aai_result = TryReadViaAccessInterface(request.path, &aai, encoder); - } - else - { - aai_result = TryReadViaAccessInterface( - request.path, AttributeAccessInterfaceRegistry::Instance().Get(request.path.mEndpointId, request.path.mClusterId), - encoder); - } + std::optional aai_result = TryReadViaAccessInterface( + request.path, AttributeAccessInterfaceRegistry::Instance().Get(request.path.mEndpointId, request.path.mClusterId), encoder); VerifyOrReturnError(!aai_result.has_value(), *aai_result); - if (!std::holds_alternative(metadata)) - { - // if we only got a cluster, this was for a global attribute. We cannot read ember attributes - // at this point, so give up (although GlobalAttributeReader should have returned something here). - chipDie(); - } const EmberAfAttributeMetadata * attributeMetadata = std::get(metadata); + // We can only get a status or metadata. + VerifyOrDie(attributeMetadata != nullptr); // At this point, we have to use ember directly to read the data. EmberAfAttributeSearchRecord record; diff --git a/src/data-model-providers/codegen/CodegenDataModelProvider_Write.cpp b/src/data-model-providers/codegen/CodegenDataModelProvider_Write.cpp index 5cd6602fe0..e0d9c159fd 100644 --- a/src/data-model-providers/codegen/CodegenDataModelProvider_Write.cpp +++ b/src/data-model-providers/codegen/CodegenDataModelProvider_Write.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -102,6 +103,7 @@ DataModel::ActionReturnStatus CodegenDataModelProvider::WriteAttribute(const Dat // and tests and implementation // // Open issue that needs fixing: https://github.com/project-chip/connectedhomeip/issues/33735 + auto metadata = Ember::FindAttributeMetadata(request.path); // Explicit failure in finding a suitable metadata @@ -110,10 +112,23 @@ DataModel::ActionReturnStatus CodegenDataModelProvider::WriteAttribute(const Dat VerifyOrDie((*status == Status::UnsupportedEndpoint) || // (*status == Status::UnsupportedCluster) || // (*status == Status::UnsupportedAttribute)); + + // Check if this is an attribute that ember does not know about but is valid after all and + // adjust the return code. All these global attributes are `read only` hence the return + // of unsupported write. + // + // If the cluster or endpoint does not exist, though, keep that return code. + if ((*status == Protocols::InteractionModel::Status::UnsupportedAttribute) && + IsSupportedGlobalAttributeNotInMetadata(request.path.mAttributeId)) + { + return Status::UnsupportedWrite; + } + return *status; } const EmberAfAttributeMetadata ** attributeMetadata = std::get_if(&metadata); + VerifyOrDie(*attributeMetadata != nullptr); // All the global attributes that we do not have metadata for are // read-only. Specifically only the following list-based attributes match the @@ -124,7 +139,7 @@ DataModel::ActionReturnStatus CodegenDataModelProvider::WriteAttribute(const Dat // - GeneratedCommands // // Given the above, UnsupportedWrite should be correct (attempt to write to a read-only list) - bool isReadOnly = (attributeMetadata == nullptr) || (*attributeMetadata)->IsReadOnly(); + bool isReadOnly = (*attributeMetadata)->IsReadOnly(); // Internal is allowed to bypass timed writes and read-only. if (!request.operationFlags.Has(DataModel::OperationFlags::kInternal)) @@ -184,10 +199,6 @@ DataModel::ActionReturnStatus CodegenDataModelProvider::WriteAttribute(const Dat Status::NeedsTimedInteraction); } - // Extra check: internal requests can bypass the read only check, however global attributes - // have no underlying storage, so write still cannot be done - VerifyOrReturnError(attributeMetadata != nullptr, Status::UnsupportedWrite); - if (request.path.mDataVersion.HasValue()) { DataVersion * versionPtr = emberAfDataVersionStorage(request.path); diff --git a/src/data-model-providers/codegen/EmberMetadata.cpp b/src/data-model-providers/codegen/EmberMetadata.cpp index 54842ee6f2..57a9b48e56 100644 --- a/src/data-model-providers/codegen/EmberMetadata.cpp +++ b/src/data-model-providers/codegen/EmberMetadata.cpp @@ -26,41 +26,26 @@ namespace Ember { using Protocols::InteractionModel::Status; -std::variant FindAttributeMetadata(const ConcreteAttributePath & aPath) { - if (IsGlobalAttribute(aPath.mAttributeId)) - { - // Global list attribute check first: during path expansion a lot of attributes - // will actually be global attributes (so not too much of a performance hit) - for (auto & attr : GlobalAttributesNotInMetadata) - { - if (attr == aPath.mAttributeId) - { - const EmberAfCluster * cluster = emberAfFindServerCluster(aPath.mEndpointId, aPath.mClusterId); - if (cluster == nullptr) - { - return (emberAfFindEndpointType(aPath.mEndpointId) == nullptr) ? Status::UnsupportedEndpoint - : Status::UnsupportedCluster; - } - - return cluster; - } - } - } const EmberAfAttributeMetadata * metadata = emberAfLocateAttributeMetadata(aPath.mEndpointId, aPath.mClusterId, aPath.mAttributeId); if (metadata == nullptr) { - Status status = ValidateClusterPath(aPath); + const EmberAfEndpointType * type = emberAfFindEndpointType(aPath.mEndpointId); + if (type == nullptr) + { + return Status::UnsupportedEndpoint; + } - if (status != Status::Success) + const EmberAfCluster * cluster = emberAfFindClusterInType(type, aPath.mClusterId, CLUSTER_MASK_SERVER); + if (cluster == nullptr) { - return status; + return Status::UnsupportedCluster; } // Since we know the attribute is unsupported and the endpoint/cluster are @@ -71,24 +56,6 @@ FindAttributeMetadata(const ConcreteAttributePath & aPath) return metadata; } -Status ValidateClusterPath(const ConcreteClusterPath & path) -{ - - const EmberAfEndpointType * type = emberAfFindEndpointType(path.mEndpointId); - if (type == nullptr) - { - return Status::UnsupportedEndpoint; - } - - const EmberAfCluster * cluster = emberAfFindClusterInType(type, path.mClusterId, CLUSTER_MASK_SERVER); - if (cluster == nullptr) - { - return Status::UnsupportedCluster; - } - - return Status::Success; -} - } // namespace Ember } // namespace app } // namespace chip diff --git a/src/data-model-providers/codegen/EmberMetadata.h b/src/data-model-providers/codegen/EmberMetadata.h index 06e1568be9..ecf6aa202f 100644 --- a/src/data-model-providers/codegen/EmberMetadata.h +++ b/src/data-model-providers/codegen/EmberMetadata.h @@ -31,26 +31,16 @@ namespace Ember { /// path. /// /// Possible return values: -/// - EmberAfCluster (NEVER null) - Only for GlobalAttributesNotInMetaData /// - EmberAfAttributeMetadata (NEVER null) - if the attribute is known to ember datastore /// - Status, only specifically for unknown attributes, may only be one of: /// - Status::UnsupportedEndpoint /// - Status::UnsupportedCluster /// - Status::UnsupportedAttribute -std::variant FindAttributeMetadata(const ConcreteAttributePath & aPath); -/// Returns the status for a given cluster existing in the ember metadata. -/// -/// Return code will be one of: -/// - Status::UnsupportedEndpoint if the path endpoint does not exist -/// - Status::UnsupportedCluster if the cluster does not exist on the given endpoint -/// - Status::Success if the cluster exists in the ember metadata. -Protocols::InteractionModel::Status ValidateClusterPath(const ConcreteClusterPath & path); - } // namespace Ember } // namespace app } // namespace chip diff --git a/src/data-model-providers/codegen/tests/BUILD.gn b/src/data-model-providers/codegen/tests/BUILD.gn index af14185ddb..57facbee09 100644 --- a/src/data-model-providers/codegen/tests/BUILD.gn +++ b/src/data-model-providers/codegen/tests/BUILD.gn @@ -20,7 +20,6 @@ source_set("ember_extra_files") { # This IS TERRIBLE, however we want to pretend AAI exists for global # items and we need a shared IO storage to reduce overhead between # data-model access and ember-compatibility (we share the same buffer) - "${chip_root}/src/app/util/ember-global-attribute-access-interface.cpp", "${chip_root}/src/app/util/ember-io-storage.cpp", "EmberInvokeOverride.cpp", "EmberInvokeOverride.h", diff --git a/src/data-model-providers/codegen/tests/TestCodegenModelViaMocks.cpp b/src/data-model-providers/codegen/tests/TestCodegenModelViaMocks.cpp index cf156a786d..4d54a194b1 100644 --- a/src/data-model-providers/codegen/tests/TestCodegenModelViaMocks.cpp +++ b/src/data-model-providers/codegen/tests/TestCodegenModelViaMocks.cpp @@ -1905,62 +1905,6 @@ TEST_F(TestCodegenModelViaMocks, AttributeAccessInterfaceListIncrementalRead) } } -TEST_F(TestCodegenModelViaMocks, ReadGlobalAttributeAttributeList) -{ - UseMockNodeConfig config(gTestNodeConfig); - CodegenDataModelProviderWithContext model; - ScopedMockAccessControl accessControl; - - ReadOperation testRequest(kMockEndpoint2, MockClusterId(3), AttributeList::Id); - testRequest.SetSubjectDescriptor(kAdminSubjectDescriptor); - - // Data read via the encoder - std::unique_ptr encoder = testRequest.StartEncoding(); - ASSERT_EQ(model.ReadAttribute(testRequest.GetRequest(), *encoder), CHIP_NO_ERROR); - ASSERT_EQ(testRequest.FinishEncoding(), CHIP_NO_ERROR); - - // Validate after read - std::vector attribute_data; - ASSERT_EQ(testRequest.GetEncodedIBs().Decode(attribute_data), CHIP_NO_ERROR); - ASSERT_EQ(attribute_data.size(), 1u); - - DecodedAttributeData & encodedData = attribute_data[0]; - ASSERT_EQ(encodedData.attributePath, testRequest.GetRequest().path); - - ASSERT_EQ(encodedData.dataReader.GetType(), TLV::kTLVType_Array); - - std::vector items; - ASSERT_EQ(DecodeList(encodedData.dataReader, items), CHIP_NO_ERROR); - - // Mock data contains ClusterRevision and FeatureMap. - // After this, Global attributes are auto-added - std::vector expected; - - // Encoding in global-attribute-access-interface has a logic of: - // - Append global attributes in front of the first specified - // large number global attribute. - // Since ClusterRevision and FeatureMap are - // global attributes, the order here is reversed for them - for (AttributeId id : GlobalAttributesNotInMetadata) - { - expected.push_back(id); - } - expected.push_back(ClusterRevision::Id); - expected.push_back(FeatureMap::Id); - expected.push_back(MockAttributeId(1)); - expected.push_back(MockAttributeId(2)); - expected.push_back(MockAttributeId(3)); - - ASSERT_EQ(items.size(), expected.size()); - - // Since we have no std::vector formatter, comparing element by element is somewhat - // more readable in case of failure. - for (unsigned i = 0; i < items.size(); i++) - { - EXPECT_EQ(items[i], expected[i]); - } -} - TEST_F(TestCodegenModelViaMocks, EmberAttributeWriteAclDeny) { UseMockNodeConfig config(gTestNodeConfig); diff --git a/src/python_testing/TestWriteReadOnlyAttributes.py b/src/python_testing/TestWriteReadOnlyAttributes.py new file mode 100644 index 0000000000..71abbc5e6e --- /dev/null +++ b/src/python_testing/TestWriteReadOnlyAttributes.py @@ -0,0 +1,115 @@ +# +# Copyright (c) 2025 Project CHIP Authors +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === +# test-runner-runs: +# run1: +# app: ${ALL_CLUSTERS_APP} +# app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json +# script-args: > +# --storage-path admin_storage.json +# --commissioning-method on-network +# --discriminator 1234 +# --passcode 20202021 +# --endpoint 1 +# --PICS src/app/tests/suites/certification/ci-pics-values +# --trace-to json:${TRACE_TEST_JSON}.json +# --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# factory-reset: true +# quiet: true +# === END CI TEST ARGUMENTS === + +import logging +from typing import cast + +import chip.clusters as Clusters +from chip.interaction_model import Status +from chip.testing.matter_testing import MatterBaseTest, async_test_body, default_matter_test_main +from mobly import asserts + +logger = logging.getLogger(__name__) + + +class TestWriteReadOnlyAttributes(MatterBaseTest): + + @async_test_body + async def test_invalid_endpoint_command(self): + self.print_step(0, "Commissioning - already done") + + self.print_step(1, "Find an invalid endpoint id") + root_parts = cast( + list[int], + await self.read_single_attribute_check_success( + cluster=Clusters.Descriptor, + attribute=Clusters.Descriptor.Attributes.PartsList, + endpoint=0, + ), + ) + endpoints = set(root_parts) + invalid_endpoint_id = 1 + while invalid_endpoint_id in endpoints: + invalid_endpoint_id += 1 + non_root_endpoint = endpoints.pop() + + # The test assumes the following known ids: + # invalid_endpoint_id - is NOT a valid endpoint in general + # non_root_endpoint - a VALID endpoint id, but it is not Endpoint0 + # In particular, root endpoint clusters should not exist there + # like AccessControl. So `non_root_endpoint/AccessControl::ClusterRevision/attributeList/...` is + # a invalid ReadOnly path + read_only_attributes = [ + Clusters.AccessControl.Attributes.ClusterRevision(123), + Clusters.AccessControl.Attributes.AcceptedCommandList([1, 2, 3]), + Clusters.AccessControl.Attributes.GeneratedCommandList([2, 3]), + Clusters.AccessControl.Attributes.AttributeList([100, 200]), + ] + + self.print_step(2, "Write read only attributes on a VALID cluster") + for attr in read_only_attributes: + asserts.assert_equal( + await self.write_single_attribute( + attr, endpoint_id=0, expect_success=False + ), + Status.UnsupportedWrite, + ) + + self.print_step( + 3, "Write read only attributes on a Invalid cluster for that endpoint" + ) + for attr in read_only_attributes: + asserts.assert_equal( + await self.write_single_attribute( + attr, endpoint_id=non_root_endpoint, expect_success=False + ), + Status.UnsupportedCluster, + ) + + self.print_step(4, "Write read only attributes on a Invalid endpoint") + for attr in read_only_attributes: + asserts.assert_equal( + await self.write_single_attribute( + attr, endpoint_id=invalid_endpoint_id, expect_success=False + ), + Status.UnsupportedEndpoint, + ) + + +if __name__ == "__main__": + default_matter_test_main() From deff77a2bb4976d4a4eff9685a136e9dc53c5b09 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Wed, 5 Feb 2025 22:41:49 -0500 Subject: [PATCH 02/39] Rename expectedResult to requiredResponse in the invokeCommands API. (#37416) The old naming was too confusing, and this more accurately represents what is actually going on. --- ...ult.h => MTRCommandWithRequiredResponse.h} | 18 ++++----- ...t.mm => MTRCommandWithRequiredResponse.mm} | 40 +++++++++---------- src/darwin/Framework/CHIP/MTRDevice.h | 4 +- src/darwin/Framework/CHIP/MTRDevice.mm | 2 +- .../Framework/CHIP/MTRDeviceController_XPC.mm | 4 +- .../Framework/CHIP/MTRDevice_Concrete.mm | 14 +++---- src/darwin/Framework/CHIP/MTRDevice_XPC.mm | 2 +- src/darwin/Framework/CHIP/Matter.h | 2 +- .../CHIP/XPC Protocol/MTRXPCServerProtocol.h | 2 +- .../Framework/CHIPTests/MTRDeviceTests.m | 18 ++++----- .../Matter.xcodeproj/project.pbxproj | 16 ++++---- 11 files changed, 61 insertions(+), 61 deletions(-) rename src/darwin/Framework/CHIP/{MTRCommandWithExpectedResult.h => MTRCommandWithRequiredResponse.h} (74%) rename src/darwin/Framework/CHIP/{MTRCommandWithExpectedResult.mm => MTRCommandWithRequiredResponse.mm} (57%) diff --git a/src/darwin/Framework/CHIP/MTRCommandWithExpectedResult.h b/src/darwin/Framework/CHIP/MTRCommandWithRequiredResponse.h similarity index 74% rename from src/darwin/Framework/CHIP/MTRCommandWithExpectedResult.h rename to src/darwin/Framework/CHIP/MTRCommandWithRequiredResponse.h index e335bc24af..385453c19d 100644 --- a/src/darwin/Framework/CHIP/MTRCommandWithExpectedResult.h +++ b/src/darwin/Framework/CHIP/MTRCommandWithRequiredResponse.h @@ -20,11 +20,11 @@ NS_ASSUME_NONNULL_BEGIN /** - * An object representing a single command to be invoked and the expected - * result of invoking it. + * An object representing a single command to be invoked and the response + * required for the invoke to be considered successful. */ MTR_AVAILABLE(ios(18.4), macos(15.4), watchos(11.4), tvos(18.4)) -@interface MTRCommandWithExpectedResult : NSObject +@interface MTRCommandWithRequiredResponse : NSObject /** * The path of the command being invoked. @@ -39,22 +39,22 @@ MTR_AVAILABLE(ios(18.4), macos(15.4), watchos(11.4), tvos(18.4)) @property (nonatomic, retain, nullable) NSDictionary * commandFields; /** - * The expected result of invoking the command. + * The response that represents this command succeeding. * * If this is nil, that indicates that the invoke is considered successful if it * does not result in an error status response. * - * If this is is not nil, then invoke is considered successful if - * it results in a data response and for each entry in the provided - * expectedResult the field whose field ID matches the key of the entry has a + * If this is is not nil, then the invoke is considered successful if + * the response is a data response and for each entry in the provided + * requiredResponse the field whose field ID matches the key of the entry has a * value that equals the value of the entry. Values of entries are data-value * dictionaries. */ -@property (nonatomic, copy, nullable) NSDictionary *> * expectedResult; +@property (nonatomic, copy, nullable) NSDictionary *> * requiredResponse; - (instancetype)initWithPath:(MTRCommandPath *)path commandFields:(nullable NSDictionary *)commandFields - expectedResult:(nullable NSDictionary *> *)expectedResult; + requiredResponse:(nullable NSDictionary *> *)requiredResponse; @end diff --git a/src/darwin/Framework/CHIP/MTRCommandWithExpectedResult.mm b/src/darwin/Framework/CHIP/MTRCommandWithRequiredResponse.mm similarity index 57% rename from src/darwin/Framework/CHIP/MTRCommandWithExpectedResult.mm rename to src/darwin/Framework/CHIP/MTRCommandWithRequiredResponse.mm index 558b7a1cc8..ddd289e57f 100644 --- a/src/darwin/Framework/CHIP/MTRCommandWithExpectedResult.mm +++ b/src/darwin/Framework/CHIP/MTRCommandWithRequiredResponse.mm @@ -18,15 +18,15 @@ #import "MTRLogging_Internal.h" #import -@implementation MTRCommandWithExpectedResult +@implementation MTRCommandWithRequiredResponse - (instancetype)initWithPath:(MTRCommandPath *)path commandFields:(nullable NSDictionary *)commandFields - expectedResult:(nullable NSDictionary *> *)expectedResult + requiredResponse:(nullable NSDictionary *> *)requiredResponse { if (self = [super init]) { self.path = path; self.commandFields = commandFields; - self.expectedResult = expectedResult; + self.requiredResponse = requiredResponse; } return self; @@ -34,19 +34,19 @@ - (instancetype)initWithPath:(MTRCommandPath *)path - (id)copyWithZone:(NSZone *)zone { - return [[MTRCommandWithExpectedResult alloc] initWithPath:self.path commandFields:self.commandFields expectedResult:self.expectedResult]; + return [[MTRCommandWithRequiredResponse alloc] initWithPath:self.path commandFields:self.commandFields requiredResponse:self.requiredResponse]; } - (NSString *)description { - return [NSString stringWithFormat:@"<%@: %p, path: %@, fields: %@, expectedResult: %@", NSStringFromClass(self.class), self, self.path, self.commandFields, self.expectedResult]; + return [NSString stringWithFormat:@"<%@: %p, path: %@, fields: %@, requiredResponse: %@", NSStringFromClass(self.class), self, self.path, self.commandFields, self.requiredResponse]; } -#pragma mark - MTRCommandWithExpectedResult NSSecureCoding implementation +#pragma mark - MTRCommandWithRequiredResponse NSSecureCoding implementation static NSString * const sPathKey = @"pathKey"; static NSString * const sFieldsKey = @"fieldsKey"; -static NSString * const sExpectedResultKey = @"expectedResultKey"; +static NSString * const sExpectedResultKey = @"requiredResponseKey"; + (BOOL)supportsSecureCoding { @@ -62,38 +62,38 @@ - (nullable instancetype)initWithCoder:(NSCoder *)decoder _path = [decoder decodeObjectOfClass:MTRCommandPath.class forKey:sPathKey]; if (!_path || ![_path isKindOfClass:MTRCommandPath.class]) { - MTR_LOG_ERROR("MTRCommandWithExpectedResult decoded %@ for endpoint, not MTRCommandPath.", _path); + MTR_LOG_ERROR("MTRCommandWithRequiredResponse decoded %@ for endpoint, not MTRCommandPath.", _path); return nil; } _commandFields = [decoder decodeObjectOfClass:NSDictionary.class forKey:sFieldsKey]; if (_commandFields) { if (![_commandFields isKindOfClass:NSDictionary.class]) { - MTR_LOG_ERROR("MTRCommandWithExpectedResult decoded %@ for commandFields, not NSDictionary.", _commandFields); + MTR_LOG_ERROR("MTRCommandWithRequiredResponse decoded %@ for commandFields, not NSDictionary.", _commandFields); return nil; } if (!MTRDataValueDictionaryIsWellFormed(_commandFields) || ![MTRStructureValueType isEqual:_commandFields[MTRTypeKey]]) { - MTR_LOG_ERROR("MTRCommandWithExpectedResult decoded %@ for commandFields, not a structure-typed data-value dictionary.", _commandFields); + MTR_LOG_ERROR("MTRCommandWithRequiredResponse decoded %@ for commandFields, not a structure-typed data-value dictionary.", _commandFields); return nil; } } - _expectedResult = [decoder decodeObjectOfClass:NSDictionary.class forKey:sExpectedResultKey]; - if (_expectedResult) { - if (![_expectedResult isKindOfClass:NSDictionary.class]) { - MTR_LOG_ERROR("MTRCommandWithExpectedResult decoded %@ for expectedResult, not NSDictionary.", _expectedResult); + _requiredResponse = [decoder decodeObjectOfClass:NSDictionary.class forKey:sExpectedResultKey]; + if (_requiredResponse) { + if (![_requiredResponse isKindOfClass:NSDictionary.class]) { + MTR_LOG_ERROR("MTRCommandWithRequiredResponse decoded %@ for requiredResponse, not NSDictionary.", _requiredResponse); return nil; } - for (id key in _expectedResult) { + for (id key in _requiredResponse) { if (![key isKindOfClass:NSNumber.class]) { - MTR_LOG_ERROR("MTRCommandWithExpectedResult decoded key %@ in expectedResult", key); + MTR_LOG_ERROR("MTRCommandWithRequiredResponse decoded key %@ in requiredResponse", key); return nil; } - if (![_expectedResult[key] isKindOfClass:NSDictionary.class] || !MTRDataValueDictionaryIsWellFormed(_expectedResult[key])) { - MTR_LOG_ERROR("MTRCommandWithExpectedResult decoded value %@ for key %@ in expectedResult", _expectedResult[key], key); + if (![_requiredResponse[key] isKindOfClass:NSDictionary.class] || !MTRDataValueDictionaryIsWellFormed(_requiredResponse[key])) { + MTR_LOG_ERROR("MTRCommandWithRequiredResponse decoded value %@ for key %@ in requiredResponse", _requiredResponse[key], key); return nil; } } @@ -111,8 +111,8 @@ - (void)encodeWithCoder:(NSCoder *)coder if (self.commandFields) { [coder encodeObject:self.commandFields forKey:sFieldsKey]; } - if (self.expectedResult) { - [coder encodeObject:self.expectedResult forKey:sExpectedResultKey]; + if (self.requiredResponse) { + [coder encodeObject:self.requiredResponse forKey:sExpectedResultKey]; } } diff --git a/src/darwin/Framework/CHIP/MTRDevice.h b/src/darwin/Framework/CHIP/MTRDevice.h index 12201d0caf..84cd4ea9c8 100644 --- a/src/darwin/Framework/CHIP/MTRDevice.h +++ b/src/darwin/Framework/CHIP/MTRDevice.h @@ -19,7 +19,7 @@ #import #import #import -#import +#import #import NS_ASSUME_NONNULL_BEGIN @@ -316,7 +316,7 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) * response. In this case the data-value representing the response will be * the value of this field. */ -- (void)invokeCommands:(NSArray *> *)commands +- (void)invokeCommands:(NSArray *> *)commands queue:(dispatch_queue_t)queue completion:(MTRDeviceResponseHandler)completion MTR_AVAILABLE(ios(18.4), macos(15.4), watchos(11.4), tvos(18.4)); diff --git a/src/darwin/Framework/CHIP/MTRDevice.mm b/src/darwin/Framework/CHIP/MTRDevice.mm index 539bf227a8..63555c8ebb 100644 --- a/src/darwin/Framework/CHIP/MTRDevice.mm +++ b/src/darwin/Framework/CHIP/MTRDevice.mm @@ -523,7 +523,7 @@ - (void)_invokeKnownCommandWithEndpointID:(NSNumber *)endpointID completion:responseHandler]; } -- (void)invokeCommands:(NSArray *> *)commands +- (void)invokeCommands:(NSArray *> *)commands queue:(dispatch_queue_t)queue completion:(MTRDeviceResponseHandler)completion { diff --git a/src/darwin/Framework/CHIP/MTRDeviceController_XPC.mm b/src/darwin/Framework/CHIP/MTRDeviceController_XPC.mm index 2108e6f48f..ac8fa52341 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceController_XPC.mm +++ b/src/darwin/Framework/CHIP/MTRDeviceController_XPC.mm @@ -150,10 +150,10 @@ - (NSXPCInterface *)_interfaceForServerProtocol argumentIndex:0 ofReply:YES]; - // invokeCommands gets handed MTRCommandWithExpectedResult (which includes + // invokeCommands gets handed MTRCommandWithRequiredResponse (which includes // MTRCommandPath, which is already in allowedClasses). [allowedClasses addObjectsFromArray:@[ - [MTRCommandWithExpectedResult class], + [MTRCommandWithRequiredResponse class], ]]; [interface setClasses:allowedClasses forSelector:@selector(deviceController:nodeID:invokeCommands:completion:) diff --git a/src/darwin/Framework/CHIP/MTRDevice_Concrete.mm b/src/darwin/Framework/CHIP/MTRDevice_Concrete.mm index d26aaf9603..0434f4890c 100644 --- a/src/darwin/Framework/CHIP/MTRDevice_Concrete.mm +++ b/src/darwin/Framework/CHIP/MTRDevice_Concrete.mm @@ -3306,7 +3306,7 @@ - (void)_invokeCommandWithEndpointID:(NSNumber *)endpointID commandFields]; } -- (BOOL)_invokeResponse:(MTRDeviceResponseValueDictionary)response matchesExpectedResult:(NSDictionary *)expectedResult +- (BOOL)_invokeResponse:(MTRDeviceResponseValueDictionary)response matchesRequiredResponse:(NSDictionary *)requiredResponse { if (response[MTRDataKey] == nil) { MTR_LOG_ERROR("%@ invokeCommands expects a data response for %@ but got no data", self, response[MTRCommandPathKey]); @@ -3321,7 +3321,7 @@ - (BOOL)_invokeResponse:(MTRDeviceResponseValueDictionary)response matchesExpect NSArray *> * fields = data[MTRValueKey]; - for (NSNumber * fieldID in expectedResult) { + for (NSNumber * fieldID in requiredResponse) { // Check that this field is present in the response. MTRDeviceDataValueDictionary _Nullable fieldValue = nil; for (NSDictionary * field in fields) { @@ -3336,7 +3336,7 @@ - (BOOL)_invokeResponse:(MTRDeviceResponseValueDictionary)response matchesExpect return NO; } - auto * expected = expectedResult[fieldID]; + auto * expected = requiredResponse[fieldID]; if (![expected isEqual:fieldValue]) { MTR_LOG_ERROR("%@ invokeCommands response for %@ field %@ got %@ but expected %@", self, response[MTRCommandPathKey], fieldID, fieldValue, expected); return NO; @@ -3346,7 +3346,7 @@ - (BOOL)_invokeResponse:(MTRDeviceResponseValueDictionary)response matchesExpect return YES; } -- (void)invokeCommands:(NSArray *> *)commands +- (void)invokeCommands:(NSArray *> *)commands queue:(dispatch_queue_t)queue completion:(MTRDeviceResponseHandler)completion { @@ -3361,10 +3361,10 @@ - (void)invokeCommands:(NSArray *> *)com // We want to invoke the command groups in order, stopping after failures as needed. Build up a // linked list of groups via chaining the completions, with calls out to the original // completion instead of going to the next list item when we want to stop. - for (NSArray * commandGroup in [commands reverseObjectEnumerator]) { + for (NSArray * commandGroup in [commands reverseObjectEnumerator]) { // We want to invoke all the commands in the group in order, propagating along the list of // current responses. Build up that linked list of command invokes via chaining the completions. - for (MTRCommandWithExpectedResult * command in [commandGroup reverseObjectEnumerator]) { + for (MTRCommandWithRequiredResponse * command in [commandGroup reverseObjectEnumerator]) { auto commandInvokeBlock = ^(BOOL allSucceededSoFar, NSArray * previousResponses) { [self invokeCommandWithEndpointID:command.path.endpoint clusterID:command.path.cluster @@ -3394,7 +3394,7 @@ - (void)invokeCommands:(NSArray *> *)com BOOL nextAllSucceeded = allSucceededSoFar; MTRDeviceResponseValueDictionary response = responses[0]; - if (command.expectedResult != nil && ![self _invokeResponse:response matchesExpectedResult:command.expectedResult]) { + if (command.requiredResponse != nil && ![self _invokeResponse:response matchesRequiredResponse:command.requiredResponse]) { nextAllSucceeded = NO; } diff --git a/src/darwin/Framework/CHIP/MTRDevice_XPC.mm b/src/darwin/Framework/CHIP/MTRDevice_XPC.mm index f1133c1428..31cf082876 100644 --- a/src/darwin/Framework/CHIP/MTRDevice_XPC.mm +++ b/src/darwin/Framework/CHIP/MTRDevice_XPC.mm @@ -459,7 +459,7 @@ - (void)_invokeCommandWithEndpointID:(NSNumber *)endpointID } } -- (void)invokeCommands:(NSArray *> *)commands +- (void)invokeCommands:(NSArray *> *)commands queue:(dispatch_queue_t)queue completion:(MTRDeviceResponseHandler)completion { diff --git a/src/darwin/Framework/CHIP/Matter.h b/src/darwin/Framework/CHIP/Matter.h index 2e5fceac06..9f7211c682 100644 --- a/src/darwin/Framework/CHIP/Matter.h +++ b/src/darwin/Framework/CHIP/Matter.h @@ -34,7 +34,7 @@ #import #import #import -#import +#import #import #import #import diff --git a/src/darwin/Framework/CHIP/XPC Protocol/MTRXPCServerProtocol.h b/src/darwin/Framework/CHIP/XPC Protocol/MTRXPCServerProtocol.h index cbe133b8ee..4e4f6a456d 100644 --- a/src/darwin/Framework/CHIP/XPC Protocol/MTRXPCServerProtocol.h +++ b/src/darwin/Framework/CHIP/XPC Protocol/MTRXPCServerProtocol.h @@ -52,7 +52,7 @@ MTR_AVAILABLE(ios(18.2), macos(15.2), watchos(11.2), tvos(18.2)) */ - (oneway void)deviceController:(NSUUID *)controller nodeID:(NSNumber *)nodeID downloadLogOfType:(MTRDiagnosticLogType)type timeout:(NSTimeInterval)timeout completion:(void (^)(NSURL * _Nullable url, NSError * _Nullable error))completion; -- (oneway void)deviceController:(NSUUID *)controller nodeID:(NSNumber *)nodeID invokeCommands:(NSArray *> *)commands completion:(MTRDeviceResponseHandler)completion MTR_AVAILABLE(ios(18.4), macos(15.4), watchos(11.4), tvos(18.4)); +- (oneway void)deviceController:(NSUUID *)controller nodeID:(NSNumber *)nodeID invokeCommands:(NSArray *> *)commands completion:(MTRDeviceResponseHandler)completion MTR_AVAILABLE(ios(18.4), macos(15.4), watchos(11.4), tvos(18.4)); @end diff --git a/src/darwin/Framework/CHIPTests/MTRDeviceTests.m b/src/darwin/Framework/CHIPTests/MTRDeviceTests.m index ae8571fe85..71f6aa29fb 100644 --- a/src/darwin/Framework/CHIPTests/MTRDeviceTests.m +++ b/src/darwin/Framework/CHIPTests/MTRDeviceTests.m @@ -5742,9 +5742,9 @@ - (void)test045_MTRDeviceInvokeGroups clusterID:@(MTRClusterIDTypeOnOffID) commandID:@(MTRCommandIDTypeClusterOnOffCommandOffID)]; - __auto_type * onCommand = [[MTRCommandWithExpectedResult alloc] initWithPath:onPath commandFields:nil expectedResult:nil]; - __auto_type * toggleCommand = [[MTRCommandWithExpectedResult alloc] initWithPath:togglePath commandFields:nil expectedResult:nil]; - __auto_type * offCommand = [[MTRCommandWithExpectedResult alloc] initWithPath:offPath commandFields:nil expectedResult:nil]; + __auto_type * onCommand = [[MTRCommandWithRequiredResponse alloc] initWithPath:onPath commandFields:nil requiredResponse:nil]; + __auto_type * toggleCommand = [[MTRCommandWithRequiredResponse alloc] initWithPath:togglePath commandFields:nil requiredResponse:nil]; + __auto_type * offCommand = [[MTRCommandWithRequiredResponse alloc] initWithPath:offPath commandFields:nil requiredResponse:nil]; XCTestExpectation * simpleInvokeDone = [self expectationWithDescription:@"Invoke of a single 3-command group done"]; [device invokeCommands:@[ @[ onCommand, toggleCommand, offCommand ] ] @@ -5773,7 +5773,7 @@ - (void)test045_MTRDeviceInvokeGroups __auto_type * failingTogglePath = [MTRCommandPath commandPathWithEndpointID:@(1000) // No such endpoint clusterID:@(MTRClusterIDTypeOnOffID) commandID:@(MTRCommandIDTypeClusterOnOffCommandToggleID)]; - __auto_type * failingToggleCommand = [[MTRCommandWithExpectedResult alloc] initWithPath:failingTogglePath commandFields:nil expectedResult:nil]; + __auto_type * failingToggleCommand = [[MTRCommandWithRequiredResponse alloc] initWithPath:failingTogglePath commandFields:nil requiredResponse:nil]; XCTestExpectation * failingWithStatusInvokeDone = [self expectationWithDescription:@"Invoke of commands where one fails with a status done"]; [device invokeCommands:@[ @[ failingToggleCommand, offCommand ], @[ onCommand, toggleCommand ], @[ failingToggleCommand ] ] @@ -5801,7 +5801,7 @@ - (void)test045_MTRDeviceInvokeGroups // Third test: Do an invoke with three groups. One of the commands in the // first group expects a data response but gets a status, which should be // treated as a failure. - __auto_type * onCommandExpectingData = [[MTRCommandWithExpectedResult alloc] initWithPath:onPath commandFields:nil expectedResult:@{ + __auto_type * onCommandExpectingData = [[MTRCommandWithRequiredResponse alloc] initWithPath:onPath commandFields:nil requiredResponse:@{ @(0) : @ { MTRTypeKey : MTRUnsignedIntegerValueType, MTRValueKey : @(0), @@ -5850,7 +5850,7 @@ - (void)test045_MTRDeviceInvokeGroups }, ] }; - __auto_type * updateFabricLabelNotExpectingFailureCommand = [[MTRCommandWithExpectedResult alloc] initWithPath:updateFabricLabelPath commandFields:updateFabricLabelFields expectedResult:nil]; + __auto_type * updateFabricLabelNotExpectingFailureCommand = [[MTRCommandWithRequiredResponse alloc] initWithPath:updateFabricLabelPath commandFields:updateFabricLabelFields requiredResponse:nil]; XCTestExpectation * updateFabricLabelNotExpectingFailureExpectation = [self expectationWithDescription:@"Invoke of commands where no failure is expected and data response is received done"]; [device invokeCommands:@[ @[ updateFabricLabelNotExpectingFailureCommand, onCommand ], @[ offCommand ] ] @@ -5889,7 +5889,7 @@ - (void)test045_MTRDeviceInvokeGroups // Fifth test: do an invoke with two groups. One of the commands in the // first group expects to get a data response and gets it, which should be // treated as success. - __auto_type * updateFabricLabelExpectingOKCommand = [[MTRCommandWithExpectedResult alloc] initWithPath:updateFabricLabelPath commandFields:updateFabricLabelFields expectedResult:@{ + __auto_type * updateFabricLabelExpectingOKCommand = [[MTRCommandWithRequiredResponse alloc] initWithPath:updateFabricLabelPath commandFields:updateFabricLabelFields requiredResponse:@{ @(0) : @ { MTRTypeKey : MTRUnsignedIntegerValueType, MTRValueKey : @(MTROperationalCredentialsNodeOperationalCertStatusOK), @@ -5933,7 +5933,7 @@ - (void)test045_MTRDeviceInvokeGroups // Sixth test: do an invoke with two groups. One of the commands in the // first group expects to get a data response with a field that it does not get, which should be // treated as failure. - __auto_type * updateFabricLabelExpectingNonexistentFieldCommand = [[MTRCommandWithExpectedResult alloc] initWithPath:updateFabricLabelPath commandFields:updateFabricLabelFields expectedResult:@{ + __auto_type * updateFabricLabelExpectingNonexistentFieldCommand = [[MTRCommandWithRequiredResponse alloc] initWithPath:updateFabricLabelPath commandFields:updateFabricLabelFields requiredResponse:@{ @(20) : @ { MTRTypeKey : MTRUnsignedIntegerValueType, MTRValueKey : @(MTROperationalCredentialsNodeOperationalCertStatusOK), @@ -5975,7 +5975,7 @@ - (void)test045_MTRDeviceInvokeGroups // Seventh test: do an invoke with two groups. One of the commands in the // first group expects to get a data response with a field value that does // not match what it gets, which should be treated as a failure. - __auto_type * updateFabricLabelExpectingWrongValueCommand = [[MTRCommandWithExpectedResult alloc] initWithPath:updateFabricLabelPath commandFields:updateFabricLabelFields expectedResult:@{ + __auto_type * updateFabricLabelExpectingWrongValueCommand = [[MTRCommandWithRequiredResponse alloc] initWithPath:updateFabricLabelPath commandFields:updateFabricLabelFields requiredResponse:@{ @(0) : @ { MTRTypeKey : MTRUnsignedIntegerValueType, MTRValueKey : @(MTROperationalCredentialsNodeOperationalCertStatusFabricConflict), diff --git a/src/darwin/Framework/Matter.xcodeproj/project.pbxproj b/src/darwin/Framework/Matter.xcodeproj/project.pbxproj index 2fd209207e..c1b0cb48c3 100644 --- a/src/darwin/Framework/Matter.xcodeproj/project.pbxproj +++ b/src/darwin/Framework/Matter.xcodeproj/project.pbxproj @@ -159,8 +159,8 @@ 512431282BA0C8BF000BC136 /* SetMRPParametersCommand.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5124311C2BA0C09A000BC136 /* SetMRPParametersCommand.mm */; }; 512431292BA0C8BF000BC136 /* ResetMRPParametersCommand.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5124311A2BA0C09A000BC136 /* ResetMRPParametersCommand.mm */; }; 5129BCFD26A9EE3300122DDF /* MTRError.h in Headers */ = {isa = PBXBuildFile; fileRef = 5129BCFC26A9EE3300122DDF /* MTRError.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 512E8E7A2D52F7B6009407E3 /* MTRCommandWithExpectedResult.mm in Sources */ = {isa = PBXBuildFile; fileRef = 512E8E792D52F7B6009407E3 /* MTRCommandWithExpectedResult.mm */; }; - 512E8E7B2D52F7B6009407E3 /* MTRCommandWithExpectedResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 512E8E782D52F7B6009407E3 /* MTRCommandWithExpectedResult.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 512E8E7A2D52F7B6009407E3 /* MTRCommandWithRequiredResponse.mm in Sources */ = {isa = PBXBuildFile; fileRef = 512E8E792D52F7B6009407E3 /* MTRCommandWithRequiredResponse.mm */; }; + 512E8E7B2D52F7B6009407E3 /* MTRCommandWithRequiredResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = 512E8E782D52F7B6009407E3 /* MTRCommandWithRequiredResponse.h */; settings = {ATTRIBUTES = (Public, ); }; }; 5131BF662BE2E1B000D5D6BC /* MTRTestCase.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5131BF642BE2E1B000D5D6BC /* MTRTestCase.mm */; }; 51339B1F2A0DA64D00C798C1 /* MTRCertificateValidityTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 51339B1E2A0DA64D00C798C1 /* MTRCertificateValidityTests.m */; }; 5136661328067D550025EDAE /* MTRDeviceController_Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 5136660F28067D540025EDAE /* MTRDeviceController_Internal.h */; }; @@ -672,8 +672,8 @@ 5124311B2BA0C09A000BC136 /* SetMRPParametersCommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SetMRPParametersCommand.h; sourceTree = ""; }; 5124311C2BA0C09A000BC136 /* SetMRPParametersCommand.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = SetMRPParametersCommand.mm; sourceTree = ""; }; 5129BCFC26A9EE3300122DDF /* MTRError.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MTRError.h; sourceTree = ""; }; - 512E8E782D52F7B6009407E3 /* MTRCommandWithExpectedResult.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MTRCommandWithExpectedResult.h; sourceTree = ""; }; - 512E8E792D52F7B6009407E3 /* MTRCommandWithExpectedResult.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MTRCommandWithExpectedResult.mm; sourceTree = ""; }; + 512E8E782D52F7B6009407E3 /* MTRCommandWithRequiredResponse.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MTRCommandWithRequiredResponse.h; sourceTree = ""; }; + 512E8E792D52F7B6009407E3 /* MTRCommandWithRequiredResponse.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MTRCommandWithRequiredResponse.mm; sourceTree = ""; }; 5131BF642BE2E1B000D5D6BC /* MTRTestCase.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MTRTestCase.mm; sourceTree = ""; }; 5131BF652BE2E1B000D5D6BC /* MTRTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MTRTestCase.h; sourceTree = ""; }; 51339B1E2A0DA64D00C798C1 /* MTRCertificateValidityTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MTRCertificateValidityTests.m; sourceTree = ""; }; @@ -1514,8 +1514,8 @@ 5178E67F2AE098510069DF72 /* MTRCommandTimedCheck.h */, 51FE723E2ACDEF3E00437032 /* MTRCommandPayloadExtensions_Internal.h */, 5178E6802AE098520069DF72 /* MTRCommissionableBrowserResult_Internal.h */, - 512E8E782D52F7B6009407E3 /* MTRCommandWithExpectedResult.h */, - 512E8E792D52F7B6009407E3 /* MTRCommandWithExpectedResult.mm */, + 512E8E782D52F7B6009407E3 /* MTRCommandWithRequiredResponse.h */, + 512E8E792D52F7B6009407E3 /* MTRCommandWithRequiredResponse.mm */, 3D010DCD2D408FA300CFFA02 /* MTRCommissioneeInfo.h */, 3D010DD12D4091C800CFFA02 /* MTRCommissioneeInfo_Internal.h */, 3D010DCE2D408FA300CFFA02 /* MTRCommissioneeInfo.mm */, @@ -1949,7 +1949,7 @@ AF1CB86E2874B03B00865A96 /* MTROTAProviderDelegate.h in Headers */, 51D0B1402B61B3A4006E3511 /* MTRServerCluster.h in Headers */, 754F3DF427FBB94B00E60580 /* MTREventTLVValueDecoder_Internal.h in Headers */, - 512E8E7B2D52F7B6009407E3 /* MTRCommandWithExpectedResult.h in Headers */, + 512E8E7B2D52F7B6009407E3 /* MTRCommandWithRequiredResponse.h in Headers */, 3CF134AF289D90FF0017A19E /* MTROperationalCertificateIssuer.h in Headers */, 5178E6822AE098520069DF72 /* MTRCommissionableBrowserResult_Internal.h in Headers */, 516415FD2B6ACA8300D5CE11 /* MTRServerAccessControl.h in Headers */, @@ -2388,7 +2388,7 @@ 514C79F02B62ADDA00DD6D7B /* descriptor.cpp in Sources */, 5109E9B42CB8B5DF0006884B /* MTRDeviceType.mm in Sources */, 3D843757294AD25A0070D20A /* MTRCertificateInfo.mm in Sources */, - 512E8E7A2D52F7B6009407E3 /* MTRCommandWithExpectedResult.mm in Sources */, + 512E8E7A2D52F7B6009407E3 /* MTRCommandWithRequiredResponse.mm in Sources */, 3D9F2FCE2D112295003CA2BB /* MTRAttributeTLVValueDecoder_Internal.mm in Sources */, 5A7947E427C0129600434CF2 /* MTRDeviceController+XPC.mm in Sources */, 7592BD0B2CC6BCC300EB74A0 /* EmberAttributeDataBuffer.cpp in Sources */, From 9db6390877f7f8c0a7e2e2239b76c3b27d17516e Mon Sep 17 00:00:00 2001 From: yunhanw-google Date: Wed, 5 Feb 2025 20:11:06 -0800 Subject: [PATCH 03/39] bump android docker versions (#37414) --- .github/workflows/full-android.yaml | 2 +- .github/workflows/smoketest-android.yaml | 2 +- integrations/cloudbuild/smoke-test.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/full-android.yaml b/.github/workflows/full-android.yaml index e8af7a4966..c0a2692b0b 100644 --- a/.github/workflows/full-android.yaml +++ b/.github/workflows/full-android.yaml @@ -39,7 +39,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-android:106 + image: ghcr.io/project-chip/chip-build-android:108 volumes: - "/tmp/log_output:/tmp/test_logs" diff --git a/.github/workflows/smoketest-android.yaml b/.github/workflows/smoketest-android.yaml index 95fe2b864e..5712f3427d 100644 --- a/.github/workflows/smoketest-android.yaml +++ b/.github/workflows/smoketest-android.yaml @@ -37,7 +37,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-android:106 + image: ghcr.io/project-chip/chip-build-android:108 volumes: - "/:/runner-root-volume" - "/tmp/log_output:/tmp/test_logs" diff --git a/integrations/cloudbuild/smoke-test.yaml b/integrations/cloudbuild/smoke-test.yaml index 002bb7e1bd..715019984f 100644 --- a/integrations/cloudbuild/smoke-test.yaml +++ b/integrations/cloudbuild/smoke-test.yaml @@ -140,7 +140,7 @@ steps: - name: pwenv path: /pwenv - - name: "ghcr.io/project-chip/chip-build-vscode:104" + - name: "ghcr.io/project-chip/chip-build-vscode:108" id: Android env: - PW_ENVIRONMENT_ROOT=/pwenv From a998bf678ef9c860134efcf769cfaedae4a773ea Mon Sep 17 00:00:00 2001 From: Yufeng Wang Date: Wed, 5 Feb 2025 21:38:23 -0800 Subject: [PATCH 04/39] Make the build_coverage script more flexible (#37415) * Make the build_coverage script more flexible * Restyled by prettier-markdown --------- Co-authored-by: Restyled.io --- docs/guides/BUILDING.md | 77 +++++++++++++++---- scripts/build_coverage.sh | 150 +++++++++++++++++++++++++------------- 2 files changed, 161 insertions(+), 66 deletions(-) diff --git a/docs/guides/BUILDING.md b/docs/guides/BUILDING.md index 6fc4695046..ae58952628 100644 --- a/docs/guides/BUILDING.md +++ b/docs/guides/BUILDING.md @@ -589,30 +589,77 @@ SDK source code has been executed. It also provides information on how often the Matter SDK executes segments of the code and produces a copy of the source file, annotated with execution frequencies. -Run the following command to initiate the script: +### How to Run + +``` +./scripts/build_coverage.sh [OPTIONS] +``` + +By default, the script + +Builds the Matter SDK with coverage instrumentation (unless you specify a custom +--output_root). Runs the unit tests to generate coverage data. Produces an HTML +coverage report located at: + +``` +out/coverage/coverage/html/index.html +``` + +You can extend the coverage scope and test types with the following options: + +Option Description -c, --code= Specify the scope to collect coverage +data. - core (default): Coverage from the core Matter SDK stack - clusters: +Coverage from cluster implementations - all: Coverage from the entire Matter SDK + +--yaml Also run YAML-based tests, in addition to unit tests. + +--python Also run Python-based tests, in addition to unit tests. + +-o, --output_root=DIR If specified, skip the build phase and only run coverage +on the provided build output directory. This directory must have been built with +use_coverage=true and have had tests run already. + +--target= When running unit tests, specifies a particular test target +to run (e.g., TestEmberAttributeBuffer.run). + +-h, --help Print script usage and exit. + +### Examples + +Run coverage with the default scope (core) and only unit tests: ``` ./scripts/build_coverage.sh ``` -By default, the code coverage script is performed at the unit testing level. -Unit tests are created by developers, thus giving them the best overview of what -tests to include in unit testing. You can extend the coverage test by scope and -ways of execution with the following parameters: +Run coverage including YAML tests (plus the always-enabled unit tests): + +``` +./scripts/build_coverage.sh --yaml +``` + +Run coverage including Python tests (plus the always-enabled unit tests): ``` - -c, --code Specify which scope to collect coverage data. - 'core': collect coverage data from core stack in Matter SDK. --default - 'clusters': collect coverage data from clusters implementation in Matter SDK. - 'all': collect coverage data from Matter SDK. - -t, --tests Specify which tools to run the coverage check. - 'unit': Run unit test to drive the coverage check. --default - 'yaml': Run yaml test to drive the coverage check. - 'all': Run unit & yaml test to drive the coverage check. +./scripts/build_coverage.sh --python ``` -Also, see the up-to-date unit testing coverage report of the Matter SDK -(collected daily) at: +Run coverage including both YAML and Python tests: + +``` +./scripts/build_coverage.sh --yaml --python +``` + +Change coverage scope to all (core + clusters) and run YAML tests: + +``` +./scripts/build_coverage.sh --code=all --yaml +``` + +### Viewing Coverage Results + +After the script completes, open the following file in your web browser to view +the HTML coverage report: [matter coverage](https://matter-build-automation.ue.r.appspot.com). ## Maintaining Matter diff --git a/scripts/build_coverage.sh b/scripts/build_coverage.sh index b754d0edaa..c9d942e845 100755 --- a/scripts/build_coverage.sh +++ b/scripts/build_coverage.sh @@ -46,37 +46,45 @@ CHIP_ROOT=$(_normpath "$(dirname "$0")/..") OUTPUT_ROOT="$CHIP_ROOT/out/coverage" COVERAGE_ROOT="$OUTPUT_ROOT/coverage" SUPPORTED_CODE=(core clusters all) -SUPPORTED_TESTS=(unit yaml all) CODE="core" -TESTS="unit" + skip_gn=false TEST_TARGET=check -help() { +# By default, do not run YAML or Python tests +ENABLE_YAML=false +ENABLE_PYTHON=false - echo "Usage: $file_name [--output_root=] [--code=] [--tests=]" +help() { + echo "Usage: $file_name [--output_root=] [--code=] [Test options" + echo + echo "Misc:" + echo " -h, --help Print this help, then exit." + echo + echo "Build/Output options:" + echo " -o, --output_root=DIR Set the build output directory." + echo " When set manually, script only runs lcov on the provided build output." + echo " This directory must be built with 'use_coverage=true' and 'ninja check' must have run." + echo + echo " -c, --code=TYPE Specify which scope to collect coverage data. One of:" + echo " core - (default) coverage from core stack in Matter SDK." + echo " clusters - coverage from cluster implementations in Matter SDK." + echo " all - coverage from entire Matter SDK." echo - echo "Misc: - -h, --help Print this help, then exit." + echo "Test options:" + echo " --yaml In addition to unit tests, run YAML-based tests." + echo " --python In addition to unit tests, run Python-based tests." + echo " Both can be combined if needed." + echo + echo " --target=TARGET Specific test target to run for unit tests (e.g. 'TestEmberAttributeBuffer.run')." echo - echo "Options: - -o, --output_root Set the build output directory. When set manually, performs only lcov stage - on provided build output. Assumes output_root has been built with 'use_coverage=true' - and that 'ninja check' was run. - -c, --code Specify which scope to collect coverage data. - 'core': collect coverage data from core stack in Matter SDK. --default - 'clusters': collect coverage data from clusters implementation in Matter SDK. - 'all': collect coverage data from Matter SDK. - -t, --tests Specify which tools to run the coverage check. - 'unit': Run unit test to drive the coverage check. --default - 'yaml': Run yaml test to drive the coverage check. - 'all': Run unit & yaml test to drive the coverage check. - --target Specific test target to run (e.g. TestEmberAttributeBuffer.run) - " } file_name=${0##*/} +# ------------------------------------------------------------------------------ +# Parse arguments +# ------------------------------------------------------------------------------ for i in "$@"; do case $i in -h | --help) @@ -87,12 +95,9 @@ for i in "$@"; do CODE="${i#*=}" shift ;; - -t=* | --tests=*) - TESTS="${i#*=}" - shift - ;; --target=*) TEST_TARGET="${i#*=}" + shift ;; -o=* | --output_root=*) OUTPUT_ROOT="${i#*=}" @@ -100,6 +105,14 @@ for i in "$@"; do skip_gn=true shift ;; + --yaml) + ENABLE_YAML=true + shift + ;; + --python) + ENABLE_PYTHON=true + shift + ;; *) echo "Unknown Option \"$1\"" echo @@ -109,49 +122,63 @@ for i in "$@"; do esac done +# Validate code argument if [[ ! " ${SUPPORTED_CODE[@]} " =~ " ${CODE} " ]]; then echo "ERROR: Code $CODE not supported" exit 1 fi -if [[ ! " ${SUPPORTED_TESTS[@]} " =~ " ${TESTS} " ]]; then - echo "ERROR: Tests $TESTS not supported" - exit 1 -fi - +# ------------------------------------------------------------------------------ +# Build & Test +# ------------------------------------------------------------------------------ if [ "$skip_gn" == false ]; then - # Ensure we have a compilation environment + # Ensure environment is set source "$CHIP_ROOT/scripts/activate.sh" - # Generates ninja files + # Generate ninja files EXTRA_GN_ARGS="" - if [[ "$TESTS" == "yaml" || "$TESTS" == "all" ]]; then + + # We only need 'chip_build_all_clusters_app' if we run YAML tests + if [ "$ENABLE_YAML" == true ]; then EXTRA_GN_ARGS="$EXTRA_GN_ARGS chip_build_all_clusters_app=true" else + # Otherwise skip building tools EXTRA_GN_ARGS="$EXTRA_GN_ARGS chip_build_tools=false" fi - gn --root="$CHIP_ROOT" gen "$OUTPUT_ROOT" --args="use_coverage=true$EXTRA_GN_ARGS" - # Run unit tests - if [[ "$TESTS" == "unit" || "$TESTS" == "all" ]]; then - ninja -C "$OUTPUT_ROOT" "$TEST_TARGET" - fi + gn --root="$CHIP_ROOT" gen "$OUTPUT_ROOT" --args="use_coverage=true $EXTRA_GN_ARGS" + + # + # 1) Always run unit tests + # + ninja -C "$OUTPUT_ROOT" "$TEST_TARGET" - # Run yaml tests - if [[ "$TESTS" == "yaml" || "$TESTS" == "all" ]]; then + # + # 2) Run YAML tests if requested + # + if [ "$ENABLE_YAML" == true ]; then ninja -C "$OUTPUT_ROOT" scripts/run_in_build_env.sh \ "./scripts/tests/run_test_suite.py \ - --chip-tool ""$OUTPUT_ROOT/chip-tool \ + --chip-tool \"$OUTPUT_ROOT/chip-tool\" \ run \ --iterations 1 \ --test-timeout-seconds 120 \ - --all-clusters-app ""$OUTPUT_ROOT/chip-all-clusters-app - " + --all-clusters-app \"$OUTPUT_ROOT/chip-all-clusters-app\"" + fi + + # + # 3) Run Python tests if requested + # + if [ "$ENABLE_PYTHON" == true ]; then + echo "Running Python tests ..." + # TODO: run python tests. fi - # Remove misc support components from coverage statistics + # ---------------------------------------------------------------------------- + # Remove objects we do NOT want included in coverage + # ---------------------------------------------------------------------------- rm -rf "$OUTPUT_ROOT/obj/src/app/app-platform" rm -rf "$OUTPUT_ROOT/obj/src/app/common" rm -rf "$OUTPUT_ROOT/obj/src/app/util/mock" @@ -162,24 +189,45 @@ if [ "$skip_gn" == false ]; then rm -rf "$OUTPUT_ROOT/obj/src/platform" rm -rf "$OUTPUT_ROOT/obj/src/tools" - # Remove unit test itself from coverage statistics + # Remove unit test objects from coverage find "$OUTPUT_ROOT/obj/src/" -depth -name 'tests' -exec rm -rf {} \; + # Restrict coverage to 'core' or 'clusters' if specified if [ "$CODE" == "core" ]; then rm -rf "$OUTPUT_ROOT/obj/src/app/clusters" elif [ "$CODE" == "clusters" ]; then mv "$OUTPUT_ROOT/obj/src/app/clusters" "$OUTPUT_ROOT/obj/clusters" rm -rf "$OUTPUT_ROOT/obj/src" - mkdir "$OUTPUT_ROOT/obj/src" + mkdir -p "$OUTPUT_ROOT/obj/src" mv "$OUTPUT_ROOT/obj/clusters" "$OUTPUT_ROOT/obj/src/clusters" fi fi +# ------------------------------------------------------------------------------ +# Coverage Generation +# ------------------------------------------------------------------------------ mkdir -p "$COVERAGE_ROOT" -lcov --initial --capture --ignore-errors inconsistent --directory "$OUTPUT_ROOT/obj/src" --exclude="$PWD"/zzz_generated/* --exclude="$PWD"/third_party/* --exclude=/usr/include/* --output-file "$COVERAGE_ROOT/lcov_base.info" -lcov --capture --ignore-errors inconsistent --directory "$OUTPUT_ROOT/obj/src" --exclude="$PWD"/zzz_generated/* --exclude="$PWD"/third_party/* --exclude=/usr/include/* --output-file "$COVERAGE_ROOT/lcov_test.info" -lcov --ignore-errors inconsistent --add-tracefile "$COVERAGE_ROOT/lcov_base.info" --add-tracefile "$COVERAGE_ROOT/lcov_test.info" --output-file "$COVERAGE_ROOT/lcov_final.info" -genhtml "$COVERAGE_ROOT/lcov_final.info" --output-directory "$COVERAGE_ROOT/html" --title "SHA:$(git rev-parse HEAD)" --header-title "Matter SDK Coverage Report" -# Copy webapp's YAML file to the coverage output directory -cp "$CHIP_ROOT/integrations/appengine/webapp_config.yaml" "$COVERAGE_ROOT/webapp_config.yaml" +lcov --initial --capture --directory "$OUTPUT_ROOT/obj/src" \ + --exclude="$PWD"/zzz_generated/* \ + --exclude="$PWD"/third_party/* \ + --exclude=/usr/include/* \ + --output-file "$COVERAGE_ROOT/lcov_base.info" + +lcov --capture --directory "$OUTPUT_ROOT/obj/src" \ + --exclude="$PWD"/zzz_generated/* \ + --exclude="$PWD"/third_party/* \ + --exclude=/usr/include/* \ + --output-file "$COVERAGE_ROOT/lcov_test.info" + +lcov --add-tracefile "$COVERAGE_ROOT/lcov_base.info" \ + --add-tracefile "$COVERAGE_ROOT/lcov_test.info" \ + --output-file "$COVERAGE_ROOT/lcov_final.info" + +genhtml "$COVERAGE_ROOT/lcov_final.info" \ + --output-directory "$COVERAGE_ROOT/html" \ + --title "SHA:$(git rev-parse HEAD)" \ + --header-title "Matter SDK Coverage Report" + +cp "$CHIP_ROOT/integrations/appengine/webapp_config.yaml" \ + "$COVERAGE_ROOT/webapp_config.yaml" From d777dce30baad3b5298346b6a1661b9a78c8a6ff Mon Sep 17 00:00:00 2001 From: joonhaengHeo <85541460+joonhaengHeo@users.noreply.github.com> Date: Fri, 7 Feb 2025 00:36:17 +0900 Subject: [PATCH 05/39] [Java] Delete finalize method in java (#37417) * Delete fialize method in java * Restyle --- .../generators/java/ChipClusters_java.jinja | 23 ++++++----- .../several_clusters/java/ChipClusters.java | 23 ++++++----- .../chip/devicecontroller/ChipClusters.java | 23 ++++++----- .../BatchInvokeCallbackJni.java | 39 ++++++++++--------- .../ChipDeviceController.java | 24 +++++++----- .../ExtendableInvokeCallbackJni.java | 25 ++++++------ .../GetConnectedDeviceCallbackJni.java | 26 +++++++------ .../devicecontroller/InvokeCallbackJni.java | 25 ++++++------ .../devicecontroller/ReportCallbackJni.java | 25 ++++++------ .../WriteAttributesCallbackJni.java | 25 ++++++------ 10 files changed, 148 insertions(+), 110 deletions(-) diff --git a/scripts/py_matter_idl/matter_idl/generators/java/ChipClusters_java.jinja b/scripts/py_matter_idl/matter_idl/generators/java/ChipClusters_java.jinja index 954bd7de57..dd2627221c 100644 --- a/scripts/py_matter_idl/matter_idl/generators/java/ChipClusters_java.jinja +++ b/scripts/py_matter_idl/matter_idl/generators/java/ChipClusters_java.jinja @@ -105,6 +105,7 @@ import chip.devicecontroller.model.NodeState; import chip.devicecontroller.model.Status; import javax.annotation.Nullable; +import java.lang.ref.Cleaner; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -169,10 +170,23 @@ public class ChipClusters { private Optional timeoutMillis = Optional.empty(); + private final Cleaner.Cleanable cleanable; + public BaseChipCluster(long devicePtr, int endpointId, long clusterId) { this.devicePtr = devicePtr; this.endpointId = endpointId; this.clusterId = clusterId; + + this.cleanable = + Cleaner.create() + .register( + this, + () -> { + if (chipClusterPtr != 0) { + deleteCluster(chipClusterPtr); + chipClusterPtr = 0; + } + }); } /** @@ -241,15 +255,6 @@ public class ChipClusters { @Deprecated public void deleteCluster(long chipClusterPtr) {} - @SuppressWarnings("deprecation") - protected void finalize() throws Throwable { - super.finalize(); - - if (chipClusterPtr != 0) { - deleteCluster(chipClusterPtr); - chipClusterPtr = 0; - } - } } abstract static class ReportCallbackImpl implements ReportCallback, SubscriptionEstablishedCallback, ResubscriptionAttemptCallback { diff --git a/scripts/py_matter_idl/matter_idl/tests/outputs/several_clusters/java/ChipClusters.java b/scripts/py_matter_idl/matter_idl/tests/outputs/several_clusters/java/ChipClusters.java index 037870ee20..997631bb47 100644 --- a/scripts/py_matter_idl/matter_idl/tests/outputs/several_clusters/java/ChipClusters.java +++ b/scripts/py_matter_idl/matter_idl/tests/outputs/several_clusters/java/ChipClusters.java @@ -28,6 +28,7 @@ import chip.devicecontroller.model.Status; import javax.annotation.Nullable; +import java.lang.ref.Cleaner; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -92,10 +93,23 @@ public static abstract class BaseChipCluster { private Optional timeoutMillis = Optional.empty(); + private final Cleaner.Cleanable cleanable; + public BaseChipCluster(long devicePtr, int endpointId, long clusterId) { this.devicePtr = devicePtr; this.endpointId = endpointId; this.clusterId = clusterId; + + this.cleanable = + Cleaner.create() + .register( + this, + () -> { + if (chipClusterPtr != 0) { + deleteCluster(chipClusterPtr); + chipClusterPtr = 0; + } + }); } /** @@ -164,15 +178,6 @@ protected void invoke( @Deprecated public void deleteCluster(long chipClusterPtr) {} - @SuppressWarnings("deprecation") - protected void finalize() throws Throwable { - super.finalize(); - - if (chipClusterPtr != 0) { - deleteCluster(chipClusterPtr); - chipClusterPtr = 0; - } - } } abstract static class ReportCallbackImpl implements ReportCallback, SubscriptionEstablishedCallback, ResubscriptionAttemptCallback { diff --git a/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java b/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java index da6e6e5c7d..b41b847b1e 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java @@ -28,6 +28,7 @@ import chip.devicecontroller.model.Status; import javax.annotation.Nullable; +import java.lang.ref.Cleaner; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -92,10 +93,23 @@ public static abstract class BaseChipCluster { private Optional timeoutMillis = Optional.empty(); + private final Cleaner.Cleanable cleanable; + public BaseChipCluster(long devicePtr, int endpointId, long clusterId) { this.devicePtr = devicePtr; this.endpointId = endpointId; this.clusterId = clusterId; + + this.cleanable = + Cleaner.create() + .register( + this, + () -> { + if (chipClusterPtr != 0) { + deleteCluster(chipClusterPtr); + chipClusterPtr = 0; + } + }); } /** @@ -164,15 +178,6 @@ protected void invoke( @Deprecated public void deleteCluster(long chipClusterPtr) {} - @SuppressWarnings("deprecation") - protected void finalize() throws Throwable { - super.finalize(); - - if (chipClusterPtr != 0) { - deleteCluster(chipClusterPtr); - chipClusterPtr = 0; - } - } } abstract static class ReportCallbackImpl implements ReportCallback, SubscriptionEstablishedCallback, ResubscriptionAttemptCallback { diff --git a/src/controller/java/src/chip/devicecontroller/BatchInvokeCallbackJni.java b/src/controller/java/src/chip/devicecontroller/BatchInvokeCallbackJni.java index 6982f58429..f873ce6add 100644 --- a/src/controller/java/src/chip/devicecontroller/BatchInvokeCallbackJni.java +++ b/src/controller/java/src/chip/devicecontroller/BatchInvokeCallbackJni.java @@ -19,17 +19,31 @@ import chip.devicecontroller.model.InvokeResponseData; import chip.devicecontroller.model.NoInvokeResponseData; +import java.lang.ref.Cleaner; import java.util.Optional; import javax.annotation.Nullable; /** JNI wrapper callback class for {@link InvokeCallback}. */ -public final class ExtendableInvokeCallbackJni { - private final ExtendableInvokeCallback wrappedExtendableInvokeCallback; +public final class BatchInvokeCallbackJni { + private final BatchInvokeCallbackJni wrappedBatchInvokeCallback; private long callbackHandle; - public ExtendableInvokeCallbackJni(ExtendableInvokeCallback wrappedExtendableInvokeCallback) { - this.wrappedExtendableInvokeCallback = wrappedExtendableInvokeCallback; + private final Cleaner.Cleanable cleanable; + + public BatchInvokeCallbackJni(BatchInvokeCallback wrappedBatchInvokeCallback) { + this.wrappedBatchInvokeCallback = wrappedBatchInvokeCallback; this.callbackHandle = newCallback(); + + this.cleanable = + Cleaner.create() + .register( + this, + () -> { + if (chipClusterPtr != 0) { + deleteCluster(chipClusterPtr); + chipClusterPtr = 0; + } + }); } long getCallbackHandle() { @@ -41,7 +55,7 @@ long getCallbackHandle() { private native void deleteCallback(long callbackHandle); private void onError(Exception e) { - wrappedExtendableInvokeCallback.onError(e); + wrappedBatchInvokeCallback.onError(e); } private void onResponse( @@ -74,21 +88,10 @@ private void onResponse( } private void onNoResponse(int commandRef) { - wrappedExtendableInvokeCallback.onNoResponse(NoInvokeResponseData.newInstance(commandRef)); + wrappedBatchInvokeCallback.onNoResponse(NoInvokeResponseData.newInstance(commandRef)); } private void onDone() { - wrappedExtendableInvokeCallback.onDone(); - } - - // TODO(#8578): Replace finalizer with PhantomReference. - @SuppressWarnings("deprecation") - protected void finalize() throws Throwable { - super.finalize(); - - if (callbackHandle != 0) { - deleteCallback(callbackHandle); - callbackHandle = 0; - } + wrappedBatchInvokeCallback.onDone(); } } diff --git a/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java b/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java index c324948974..893307be21 100644 --- a/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java +++ b/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java @@ -26,6 +26,7 @@ import chip.devicecontroller.model.ChipEventPath; import chip.devicecontroller.model.DataVersionFilter; import chip.devicecontroller.model.InvokeElement; +import java.lang.ref.Cleaner; import java.time.ZoneOffset; import java.util.ArrayList; import java.util.Calendar; @@ -44,6 +45,8 @@ public class ChipDeviceController { private ScanNetworksListener scanNetworksListener; private NOCChainIssuer nocChainIssuer; + private final Cleaner.Cleanable cleanable; + /** * To load class and jni, we need to new AndroidChipPlatform after jni load but before new * ChipDeviceController @@ -67,6 +70,17 @@ public ChipDeviceController(ControllerParams params) { throw new NullPointerException("params cannot be null"); } deviceControllerPtr = newDeviceController(params); + + this.cleanable = + Cleaner.create() + .register( + this, + () -> { + if (deviceControllerPtr != 0) { + deleteDeviceController(deviceControllerPtr); + deviceControllerPtr = 0; + } + }); } public void setCompletionListener(CompletionListener listener) { @@ -1773,16 +1787,6 @@ private native void updateCommissioningICDRegistrationInfo( System.loadLibrary("CHIPController"); } - @SuppressWarnings("deprecation") - protected void finalize() throws Throwable { - super.finalize(); - - if (deviceControllerPtr != 0) { - deleteDeviceController(deviceControllerPtr); - deviceControllerPtr = 0; - } - } - /** Interface to implement custom operational credentials issuer (NOC chain generation). */ public interface NOCChainIssuer { /** diff --git a/src/controller/java/src/chip/devicecontroller/ExtendableInvokeCallbackJni.java b/src/controller/java/src/chip/devicecontroller/ExtendableInvokeCallbackJni.java index 6982f58429..6c12940fb6 100644 --- a/src/controller/java/src/chip/devicecontroller/ExtendableInvokeCallbackJni.java +++ b/src/controller/java/src/chip/devicecontroller/ExtendableInvokeCallbackJni.java @@ -19,6 +19,7 @@ import chip.devicecontroller.model.InvokeResponseData; import chip.devicecontroller.model.NoInvokeResponseData; +import java.lang.ref.Cleaner; import java.util.Optional; import javax.annotation.Nullable; @@ -27,9 +28,22 @@ public final class ExtendableInvokeCallbackJni { private final ExtendableInvokeCallback wrappedExtendableInvokeCallback; private long callbackHandle; + private final Cleaner.Cleanable cleanable; + public ExtendableInvokeCallbackJni(ExtendableInvokeCallback wrappedExtendableInvokeCallback) { this.wrappedExtendableInvokeCallback = wrappedExtendableInvokeCallback; this.callbackHandle = newCallback(); + + this.cleanable = + Cleaner.create() + .register( + this, + () -> { + if (callbackHandle != 0) { + deleteCallback(callbackHandle); + callbackHandle = 0; + } + }); } long getCallbackHandle() { @@ -80,15 +94,4 @@ private void onNoResponse(int commandRef) { private void onDone() { wrappedExtendableInvokeCallback.onDone(); } - - // TODO(#8578): Replace finalizer with PhantomReference. - @SuppressWarnings("deprecation") - protected void finalize() throws Throwable { - super.finalize(); - - if (callbackHandle != 0) { - deleteCallback(callbackHandle); - callbackHandle = 0; - } - } } diff --git a/src/controller/java/src/chip/devicecontroller/GetConnectedDeviceCallbackJni.java b/src/controller/java/src/chip/devicecontroller/GetConnectedDeviceCallbackJni.java index b45b04a778..84338f8234 100644 --- a/src/controller/java/src/chip/devicecontroller/GetConnectedDeviceCallbackJni.java +++ b/src/controller/java/src/chip/devicecontroller/GetConnectedDeviceCallbackJni.java @@ -17,14 +17,29 @@ */ package chip.devicecontroller; +import java.lang.ref.Cleaner; + /** JNI wrapper callback class for getting a connected device. */ public class GetConnectedDeviceCallbackJni { private final GetConnectedDeviceCallback wrappedCallback; private long callbackHandle; + private final Cleaner.Cleanable cleanable; + public GetConnectedDeviceCallbackJni(GetConnectedDeviceCallback wrappedCallback) { this.wrappedCallback = wrappedCallback; this.callbackHandle = newCallback(wrappedCallback); + + this.cleanable = + Cleaner.create() + .register( + this, + () -> { + if (callbackHandle != 0) { + deleteCallback(callbackHandle); + callbackHandle = 0; + } + }); } long getCallbackHandle() { @@ -35,17 +50,6 @@ long getCallbackHandle() { private native void deleteCallback(long callbackHandle); - // TODO(#8578): Replace finalizer with PhantomReference. - @SuppressWarnings("deprecation") - protected void finalize() throws Throwable { - super.finalize(); - - if (callbackHandle != 0) { - deleteCallback(callbackHandle); - callbackHandle = 0; - } - } - /** Callbacks for getting a device connected with PASE or CASE, depending on the context. */ public interface GetConnectedDeviceCallback { void onDeviceConnected(long devicePointer); diff --git a/src/controller/java/src/chip/devicecontroller/InvokeCallbackJni.java b/src/controller/java/src/chip/devicecontroller/InvokeCallbackJni.java index ceb35eccef..69881a7784 100644 --- a/src/controller/java/src/chip/devicecontroller/InvokeCallbackJni.java +++ b/src/controller/java/src/chip/devicecontroller/InvokeCallbackJni.java @@ -18,15 +18,29 @@ package chip.devicecontroller; import chip.devicecontroller.model.InvokeElement; +import java.lang.ref.Cleaner; /** JNI wrapper callback class for {@link InvokeCallback}. */ public final class InvokeCallbackJni { private final InvokeCallback wrappedInvokeCallback; private long callbackHandle; + private final Cleaner.Cleanable cleanable; + public InvokeCallbackJni(InvokeCallback wrappedInvokeCallback) { this.wrappedInvokeCallback = wrappedInvokeCallback; this.callbackHandle = newCallback(); + + this.cleanable = + Cleaner.create() + .register( + this, + () -> { + if (callbackHandle != 0) { + deleteCallback(callbackHandle); + callbackHandle = 0; + } + }); } long getCallbackHandle() { @@ -55,15 +69,4 @@ private void onResponse( private void onDone() { wrappedInvokeCallback.onDone(); } - - // TODO(#8578): Replace finalizer with PhantomReference. - @SuppressWarnings("deprecation") - protected void finalize() throws Throwable { - super.finalize(); - - if (callbackHandle != 0) { - deleteCallback(callbackHandle); - callbackHandle = 0; - } - } } diff --git a/src/controller/java/src/chip/devicecontroller/ReportCallbackJni.java b/src/controller/java/src/chip/devicecontroller/ReportCallbackJni.java index 4f2529fa8d..9ff86d1e9f 100644 --- a/src/controller/java/src/chip/devicecontroller/ReportCallbackJni.java +++ b/src/controller/java/src/chip/devicecontroller/ReportCallbackJni.java @@ -20,6 +20,7 @@ import chip.devicecontroller.model.ChipAttributePath; import chip.devicecontroller.model.ChipEventPath; import chip.devicecontroller.model.NodeState; +import java.lang.ref.Cleaner; import javax.annotation.Nullable; /** JNI wrapper callback class for {@link ReportCallback}. */ @@ -30,6 +31,8 @@ public class ReportCallbackJni { private long callbackHandle; @Nullable private NodeState nodeState; + private final Cleaner.Cleanable cleanable; + public ReportCallbackJni( @Nullable SubscriptionEstablishedCallback subscriptionEstablishedCallback, ReportCallback reportCallback, @@ -39,6 +42,17 @@ public ReportCallbackJni( this.wrappedResubscriptionAttemptCallback = resubscriptionAttemptCallback; this.callbackHandle = newCallback(subscriptionEstablishedCallback, resubscriptionAttemptCallback); + + this.cleanable = + Cleaner.create() + .register( + this, + () -> { + if (callbackHandle != 0) { + deleteCallback(callbackHandle); + callbackHandle = 0; + } + }); } long getCallbackHandle() { @@ -88,15 +102,4 @@ private void onError( private void onDone() { wrappedReportCallback.onDone(); } - - // TODO(#8578): Replace finalizer with PhantomReference. - @SuppressWarnings("deprecation") - protected void finalize() throws Throwable { - super.finalize(); - - if (callbackHandle != 0) { - deleteCallback(callbackHandle); - callbackHandle = 0; - } - } } diff --git a/src/controller/java/src/chip/devicecontroller/WriteAttributesCallbackJni.java b/src/controller/java/src/chip/devicecontroller/WriteAttributesCallbackJni.java index 7b95b30759..84a74c4d9e 100644 --- a/src/controller/java/src/chip/devicecontroller/WriteAttributesCallbackJni.java +++ b/src/controller/java/src/chip/devicecontroller/WriteAttributesCallbackJni.java @@ -19,6 +19,7 @@ import chip.devicecontroller.model.ChipAttributePath; import chip.devicecontroller.model.Status; +import java.lang.ref.Cleaner; import javax.annotation.Nullable; /** JNI wrapper callback class for {@link WriteAttributesCallback}. */ @@ -26,9 +27,22 @@ public final class WriteAttributesCallbackJni { private final WriteAttributesCallback wrappedWriteAttributesCallback; private long callbackHandle; + private final Cleaner.Cleanable cleanable; + public WriteAttributesCallbackJni(WriteAttributesCallback wrappedWriteAttributesCallback) { this.wrappedWriteAttributesCallback = wrappedWriteAttributesCallback; this.callbackHandle = newCallback(); + + this.cleanable = + Cleaner.create() + .register( + this, + () -> { + if (callbackHandle != 0) { + deleteCallback(callbackHandle); + callbackHandle = 0; + } + }); } long getCallbackHandle() { @@ -61,15 +75,4 @@ private void onResponse( private void onDone() { wrappedWriteAttributesCallback.onDone(); } - - // TODO(#8578): Replace finalizer with PhantomReference. - @SuppressWarnings("deprecation") - protected void finalize() throws Throwable { - super.finalize(); - - if (callbackHandle != 0) { - deleteCallback(callbackHandle); - callbackHandle = 0; - } - } } From 8ec9b41e85884e3d67f13d01fcfa8511688c8eb9 Mon Sep 17 00:00:00 2001 From: Arkadiusz Bokowy Date: Thu, 6 Feb 2025 17:02:32 +0100 Subject: [PATCH 06/39] [Tizen] Fix race when storing cert credentials (#37427) --- integrations/docker/images/base/chip-build/version | 2 +- .../chip-build-tizen/tizen-sdk-installer/secret-tool.py | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/integrations/docker/images/base/chip-build/version b/integrations/docker/images/base/chip-build/version index d69741af1b..b0158daf67 100644 --- a/integrations/docker/images/base/chip-build/version +++ b/integrations/docker/images/base/chip-build/version @@ -1 +1 @@ -108 : Update vscode docker with java17 and fix java_home in java docker +109 : [Tizen] Fix race when storing cert credentials diff --git a/integrations/docker/images/stage-2/chip-build-tizen/tizen-sdk-installer/secret-tool.py b/integrations/docker/images/stage-2/chip-build-tizen/tizen-sdk-installer/secret-tool.py index c6807ab9a6..e94ae54c77 100755 --- a/integrations/docker/images/stage-2/chip-build-tizen/tizen-sdk-installer/secret-tool.py +++ b/integrations/docker/images/stage-2/chip-build-tizen/tizen-sdk-installer/secret-tool.py @@ -61,6 +61,7 @@ def _save(self): self.fp.seek(0) self.fp.truncate() pickle.dump(self.secrets, self.fp) + self.fp.flush() except IOError as e: print("ERROR: " + str(e), file=sys.stderr) @@ -92,14 +93,14 @@ def lookup(self, label: str, **kw): subparsers = parser.add_subparsers(dest='command', required=True) parser_clear = subparsers.add_parser( - "clear", help="Remove passward associated with given key value pairs") + "clear", help="Remove password associated with given key value pairs") parser_clear.add_argument("-l", "--label", action='store', required=True, help="label for given key value pairs") parser_clear.add_argument("kw", nargs='*', help="key value pairs") parser_store = subparsers.add_parser( - "store", help="Store passward for given key value pairs") + "store", help="Store password for given key value pairs") parser_store.add_argument("-l", "--label", action='store', required=True, help="label for given key value pairs") parser_store.add_argument("-p", "--password", action='store', required=True, @@ -108,7 +109,7 @@ def lookup(self, label: str, **kw): help="key value pairs") parser_lookup = subparsers.add_parser( - "lookup", help="Retrieve passward associated with given key value pairs") + "lookup", help="Retrieve password associated with given key value pairs") parser_lookup.add_argument("-l", "--label", action='store', required=True, help="label for given key value pairs") parser_lookup.add_argument("kw", nargs='*', From 7adac6e7a42aa52366d43170cc9d050608b762e0 Mon Sep 17 00:00:00 2001 From: Pradip De Date: Thu, 6 Feb 2025 16:31:19 +0000 Subject: [PATCH 07/39] Add test steps logging for TCP Tests (#37397) * Add test steps logging for TCP Tests * Fix naming of Test steps. --- src/python_testing/TCP_Tests.py | 140 ++++++++++++++++++++++++++++++-- 1 file changed, 132 insertions(+), 8 deletions(-) diff --git a/src/python_testing/TCP_Tests.py b/src/python_testing/TCP_Tests.py index f38cdb5651..6e36085c3d 100644 --- a/src/python_testing/TCP_Tests.py +++ b/src/python_testing/TCP_Tests.py @@ -33,7 +33,7 @@ import chip.clusters as Clusters from chip import ChipDeviceCtrl from chip.interaction_model import InteractionModelError -from chip.testing.matter_testing import MatterBaseTest, async_test_body, default_matter_test_main +from chip.testing.matter_testing import MatterBaseTest, TestStep, async_test_body, default_matter_test_main from mobly import asserts @@ -48,141 +48,265 @@ async def teardown_test(self): await self.send_single_cmd(cmd=cmd, endpoint=0, payloadCapability=ChipDeviceCtrl.TransportPayloadCapability.LARGE_PAYLOAD) - def pics_SC_8_1(self): + def pics_TC_SC_8_1(self): return ['MCORE.SC.TCP'] + def steps_TC_SC_8_1(self) -> list[TestStep]: + steps = [ + TestStep(1, "Commissioning, already done", is_commissioning=True), + TestStep(2, "TH initiates a CASE session establishment with DUT, requesting a session supporting large payloads."), + TestStep(3, "Verifying that a session is set up with an underlying TCP connection established with DUT."), + ] + return steps + # TCP Connection Establishment @async_test_body async def test_TC_SC_8_1(self): + self.step(1) try: + self.step(2) device = await self.default_controller.GetConnectedDevice(nodeid=self.dut_node_id, allowPASE=False, timeoutMs=1000, payloadCapability=ChipDeviceCtrl.TransportPayloadCapability.LARGE_PAYLOAD) except TimeoutError: asserts.fail("Unable to establish a CASE session over TCP to the device") + + self.step(3) asserts.assert_equal(device.isSessionOverTCPConnection, True, "Session does not have associated TCP connection") asserts.assert_equal(device.isActiveSession, True, "Large Payload Session should be active over TCP connection") - def pics_SC_8_2(self): + def pics_TC_SC_8_2(self): return ['MCORE.SC.TCP'] + def steps_TC_SC_8_2(self) -> list[TestStep]: + steps = [ + TestStep(1, "Commissioning, already done", is_commissioning=True), + TestStep(2, "TH initiates a CASE session establishment with DUT, requesting a session supporting large payloads."), + TestStep(3, "Verifying that the session established with DUT allows large payloads."), + ] + return steps + # Large Payload Session Establishment @async_test_body async def test_TC_SC_8_2(self): + self.step(1) try: + self.step(2) device = await self.default_controller.GetConnectedDevice(nodeid=self.dut_node_id, allowPASE=False, timeoutMs=1000, payloadCapability=ChipDeviceCtrl.TransportPayloadCapability.LARGE_PAYLOAD) except TimeoutError: asserts.fail("Unable to establish a CASE session over TCP to the device") + + self.step(3) asserts.assert_equal(device.sessionAllowsLargePayload, True, "Session does not have associated TCP connection") - def pics_SC_8_3(self): + def pics_TC_SC_8_3(self): return ['MCORE.SC.TCP'] + def steps_TC_SC_8_3(self) -> list[TestStep]: + steps = [ + TestStep(1, "Commissioning, already done", is_commissioning=True), + TestStep(2, "TH initiates a CASE session establishment with DUT, requesting a session supporting large payloads."), + TestStep(3, "Verifying that a session is set up with an underlying TCP connection established with DUT."), + TestStep(4, "TH closes the TCP connection with DUT"), + TestStep(5, "Verifying that the secure session with DUT is inactive."), + ] + return steps + # Session Inactive After TCP Disconnect @async_test_body async def test_TC_SC_8_3(self): + self.step(1) try: + self.step(2) device = await self.default_controller.GetConnectedDevice(nodeid=self.dut_node_id, allowPASE=False, timeoutMs=1000, payloadCapability=ChipDeviceCtrl.TransportPayloadCapability.LARGE_PAYLOAD) except TimeoutError: asserts.fail("Unable to establish a CASE session over TCP to the device") + + self.step(3) asserts.assert_equal(device.isSessionOverTCPConnection, True, "Session does not have associated TCP connection") + self.step(4) device.closeTCPConnectionWithPeer() + + self.step(5) asserts.assert_equal(device.isActiveSession, False, "Large Payload Session should not be active after TCP connection closure") - def pics_SC_8_4(self): + def pics_TC_SC_8_4(self): return ['MCORE.SC.TCP'] + def steps_TC_SC_8_4(self) -> list[TestStep]: + steps = [ + TestStep(1, "Commissioning, already done", is_commissioning=True), + TestStep(2, "TH initiates a CASE session establishment with DUT, requesting a session supporting large payloads."), + TestStep(3, "Verifying that a session is set up with an underlying TCP connection established with DUT."), + TestStep(4, "TH closes the TCP connection with DUT"), + TestStep(5, "Verifyng that the secure session with DUT is inactive."), + TestStep(6, "TH re-initiates CASE session establishment over TCP with DUT"), + TestStep(7, "Verifying that a session is set up with an underlying TCP connection established with DUT."), + TestStep(8, "Verifying that the large-payload secure session with DUT is active."), + ] + return steps + # TCP Connect, Disconnect, Then Connect Again @async_test_body async def test_TC_SC_8_4(self): + self.step(1) try: + self.step(2) device = await self.default_controller.GetConnectedDevice(nodeid=self.dut_node_id, allowPASE=False, timeoutMs=1000, payloadCapability=ChipDeviceCtrl.TransportPayloadCapability.LARGE_PAYLOAD) except TimeoutError: asserts.fail("Unable to establish a CASE session over TCP to the device") + + self.step(3) asserts.assert_equal(device.isSessionOverTCPConnection, True, "Session does not have associated TCP connection") + self.step(4) device.closeTCPConnectionWithPeer() + + self.step(5) asserts.assert_equal(device.isActiveSession, False, "Large Payload Session should not be active after TCP connection closure") # Connect again try: + self.step(6) device = await self.default_controller.GetConnectedDevice(nodeid=self.dut_node_id, allowPASE=False, timeoutMs=1000, payloadCapability=ChipDeviceCtrl.TransportPayloadCapability.LARGE_PAYLOAD) except TimeoutError: asserts.fail("Unable to establish a CASE session over TCP to the device") + + self.step(7) asserts.assert_equal(device.isSessionOverTCPConnection, True, "Session does not have associated TCP connection") + + self.step(8) asserts.assert_equal(device.isActiveSession, True, "Large Payload Session should be active over TCP connection") - def pics_SC_8_5(self): + def pics_TC_SC_8_5(self): return ['MCORE.SC.TCP'] + def steps_TC_SC_8_5(self) -> list[TestStep]: + steps = [ + TestStep(1, "Commissioning, already done", is_commissioning=True), + TestStep(2, "TH initiates a CASE session establishment with DUT, requesting a session supporting large payloads."), + TestStep(3, "Verifying that a session is set up with an underlying TCP connection established with DUT."), + TestStep(4, "Verifying that the large-payload secure session with DUT is active."), + TestStep(5, "TH initiates an InvokeCommandRequest with DUT over the established session."), + TestStep(6, "Verifying successful invocation with DUT over the established session without any error."), + ] + return steps + @async_test_body async def test_TC_SC_8_5(self): + self.step(1) try: + self.step(2) device = await self.default_controller.GetConnectedDevice(nodeid=self.dut_node_id, allowPASE=False, timeoutMs=1000, payloadCapability=ChipDeviceCtrl.TransportPayloadCapability.LARGE_PAYLOAD) except TimeoutError: asserts.fail("Unable to establish a CASE session over TCP to the device") + + self.step(3) asserts.assert_equal(device.isSessionOverTCPConnection, True, "Session does not have associated TCP connection") + + self.step(4) asserts.assert_equal(device.isActiveSession, True, "Large Payload Session should be active over TCP connection") asserts.assert_equal(device.sessionAllowsLargePayload, True, "Session does not have associated TCP connection") try: + self.step(5) await self.send_arm_cmd(ChipDeviceCtrl.TransportPayloadCapability.LARGE_PAYLOAD) except InteractionModelError: asserts.fail("Unexpected error returned by DUT") + self.step(6) - def pics_SC_8_6(self): + def pics_TC_SC_8_6(self): return ['MCORE.SC.TCP'] + def steps_TC_SC_8_6(self) -> list[TestStep]: + steps = [ + TestStep(1, "Commissioning, already done", is_commissioning=True), + TestStep(2, "TH initiates a CASE session establishment with DUT, requesting a session supporting large payloads."), + TestStep(3, "Verifying that a session is set up with an underlying TCP connection established with DUT."), + TestStep(4, "Verifying that the large-payload secure session with DUT is active."), + TestStep(5, "TH initiates a Read of all attributes of all clusters of DUT."), + TestStep(6, "Verifying wildcard read was successful with DUT over the established session without any error."), + ] + return steps + # WildCard Read Over TCP Session @async_test_body async def test_TC_SC_8_6(self): + self.step(1) try: + self.step(2) device = await self.default_controller.GetConnectedDevice(nodeid=self.dut_node_id, allowPASE=False, timeoutMs=1000, payloadCapability=ChipDeviceCtrl.TransportPayloadCapability.LARGE_PAYLOAD) except TimeoutError: asserts.fail("Unable to establish a CASE session over TCP to the device") + + self.step(3) asserts.assert_equal(device.isSessionOverTCPConnection, True, "Session does not have associated TCP connection") + + self.step(4) asserts.assert_equal(device.isActiveSession, True, "Large Payload Session should be active over TCP connection") asserts.assert_equal(device.sessionAllowsLargePayload, True, "Session does not have associated TCP connection") try: + self.step(5) await self.default_controller.Read(self.dut_node_id, [()], payloadCapability=ChipDeviceCtrl.TransportPayloadCapability.LARGE_PAYLOAD) except InteractionModelError: asserts.fail("Unexpected error returned by DUT") + self.step(6) - def pics_SC_8_7(self): + def pics_TC_SC_8_7(self): return ['MCORE.SC.TCP'] + def steps_TC_SC_8_7(self) -> list[TestStep]: + steps = [ + TestStep(1, "Commissioning, already done", is_commissioning=True), + TestStep(2, "TH initiates a CASE session establishment with DUT, requesting a session supporting large payloads."), + TestStep(3, "Verifying that a session is set up with an underlying TCP connection established with DUT."), + TestStep(4, "Verifying that the large-payload secure session with DUT is active."), + TestStep(5, "TH initiates a regularly-sized InvokeCommandRequest with DUT, specifying that either a MRP or TCP-based session is usable."), + TestStep(6, "Verifying successful invocation with DUT over the established TCP-based session without any error."), + ] + return steps + # Use TCP Session If Available For MRP Interaction @async_test_body async def test_TC_SC_8_7(self): + self.step(1) + try: + self.step(2) device = await self.default_controller.GetConnectedDevice(nodeid=self.dut_node_id, allowPASE=False, timeoutMs=1000, payloadCapability=ChipDeviceCtrl.TransportPayloadCapability.LARGE_PAYLOAD) except TimeoutError: asserts.fail("Unable to establish a CASE session over TCP to the device") + + self.step(3) asserts.assert_equal(device.isSessionOverTCPConnection, True, "Session does not have associated TCP connection") + + self.step(4) asserts.assert_equal(device.isActiveSession, True, "Large Payload Session should be active over TCP connection") asserts.assert_equal(device.sessionAllowsLargePayload, True, "Session does not have associated TCP connection") try: + self.step(5) self.send_arm_cmd(ChipDeviceCtrl.TransportPayloadCapability.MRP_OR_TCP_PAYLOAD) except InteractionModelError: asserts.fail("Unexpected error returned by DUT") + self.step(6) if __name__ == "__main__": From 779221f0b39eb010e2d241e95e1f0d8578f4cbf9 Mon Sep 17 00:00:00 2001 From: Ashwini <98016634+Ashwinigrl@users.noreply.github.com> Date: Thu, 6 Feb 2025 23:02:39 +0530 Subject: [PATCH 08/39] [TC-DLOG-2.1] Updated the Manual script as per the Verification step document. (#37098) * Test Steps 2, 3, 4, 2a, 3a, 4a, 2b, 3b, 4b,6, 7, 8, 10, 13 are updated with the boolean flag(SendInitMsgfromDUT ) true and false condition * Restyled by whitespace --------- Co-authored-by: Restyled.io --- .../certification/Test_TC_DLOG_2_1.yaml | 289 ++++++++++++++---- 1 file changed, 234 insertions(+), 55 deletions(-) diff --git a/src/app/tests/suites/certification/Test_TC_DLOG_2_1.yaml b/src/app/tests/suites/certification/Test_TC_DLOG_2_1.yaml index ebc658f165..cedff5b898 100644 --- a/src/app/tests/suites/certification/Test_TC_DLOG_2_1.yaml +++ b/src/app/tests/suites/certification/Test_TC_DLOG_2_1.yaml @@ -34,18 +34,24 @@ tests: Length of TransferFileDesignator is equal to 32 characters Length of TransferFileDesignator is greater than 32 characters To send a message that mismatches the current transfer mode + + Note: + https://github.com/CHIP-Specifications/chip-test-plans/blob/master/src/cluster/logs_diagnostics.adoc#pre-conditions + 1. Execute the below commands in the interactive mode: - ./chip-tool interactive start - 2. Before running the below steps ensure that \tmp folder on the system does not contain the below files. - If they are present please delete these files: - TH_LOG_OK_NORMAL : "Length_1234567.txt" - TH_LOG_OK_FULL_LENGTH : "Length_123456789123456789123.txt" - 3. Use the below command in the all-cluster-app for setting up the diagonistics logs. - ./chip-all-clusters-app --trace_decode 1 --end_user_support_log ~/tmp/end_user_support_log.txt --network_diagnostics_log ~/tmp/nw_log.txt --crash_log ~/tmp/crash_log.txt + ./chip-tool interactive start + 2. Before running the below steps ensure that \tmp folder on the system does not contain the below files. If they are present please delete these files + TH_LOG_OK_NORMAL : "Length_1234567.txt" + TH_LOG_OK_FULL_LENGTH : "Length_123456789123456789123.txt" + 3. + NOTE : The below setting is shown for sample, DUT can be setting logs of any size. + + Use the below command in the all-cluster-app for setting up the diagonistics logs. + ./chip-all-clusters-app --trace_decode 1 --end_user_support_log ~/tmp/end_user_support_log.txt --network_diagnostics_log ~/tmp/nw_log.txt --crash_log ~/tmp/crash_log.txt The log file content can be set such that the file size can be as follows to obtain different status code from DUT: 1. end_user_support_log > 1024 bytes 2. Make sure that nw_log.txt does not exist - 3. crash_log < 1024 bytes + 3. crash_log <= 1024 bytes disabled: true - label: "Step 1: Commission DUT to TH" @@ -62,7 +68,10 @@ tests: verification: | diagnosticlogs retrieve-logs-request 0 1 1 0 --TransferFileDesignator Length_123456789123456789123.txt - On TH(chip-tool), Verify that the DUT sends SendInit message with TransferFileDesignator field set to Length_1234567891234567891 + If DUT sends SendInit message (BDX inititation happens from DUT) + SendInitMsgfromDUT = true + + On TH(chip-tool), Verify that the DUT sends SendInit message with TransferFileDesignator field set to Length_123456789123456789123.txt 1707966626.594544][10635:10638] CHIP:ATM: SendInit [1707966626.594550][10635:10638] CHIP:ATM: Proposed Transfer Control: 0x10 @@ -73,8 +82,7 @@ tests: [1707966626.594584][10635:10638] CHIP:ATM: File Designator Length: 32 [1707966626.594588][10635:10638] CHIP:ATM: File Designator: Length_123456789123456789123.txt - Note: end_user_support_log > 1024 bytes so that BDX inititation happens from DUT - SendInitMsgfromDUT = true + Else SendInitMsgfromDUT = false (DUT does not send SendInit message) disabled: true - label: @@ -82,7 +90,10 @@ tests: message to DUT" PICS: MCORE.BDX.Initiator verification: | - On chip-tool TH will send the SendAccept Message to the DUT + If SendInitMsgfromDUT = true proceed with the following validation: + + 1. Message Flow: + On chip-tool (TH): Send the SendAccept message to the DUT: [1707894873.734698][34353:34356] CHIP:ATM: Sending BDX Message [1707894873.734710][34353:34356] CHIP:ATM: SendAccept @@ -90,32 +101,58 @@ tests: [1707894873.734720][34353:34356] CHIP:ATM: Max Block Size: 1024 [1707894874.235405][34353:34356] CHIP:BDX: Got an event MsgToSend - On TH(chip-tool), verify that the DUT responds by sending RetrieveLogsResponse Command with Success(0) status code to TH after receiving the SendAccept Message + On TH (chip-tool): Verify that the DUT responds with the RetrieveLogsResponse command with a Success(0) status code and LogContent field is empty + 1707894874.239127][34353:34356] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_0032 Command 0x0000_0001 [1707894874.239189][34353:34356] CHIP:TOO: RetrieveLogsResponse: { [1707894874.239208][34353:34356] CHIP:TOO: status: 0 [1707894874.239219][34353:34356] CHIP:TOO: logContent: [1707894874.239227][34353:34356] CHIP:TOO: } - Check for the size of the file that was specified in the File Deginator field of the RetrieveLogsRequest Command sent to DUT and verify that the size is greater than 1024 bytes. - The file: Length_123456789123456789123.txt (as mentioned in the file designator field) is transferred to /tmp folder on the build system and the size is > 1024 bytes + 2. File Transfer Verification: + - Check the size of the file specified in the File Designator field of the RetrieveLogsRequest command. + - Confirm that the size is greater than 1024 bytes. + - Example file: Length_123456789123456789123.txt + - Verify that the file is transferred to the /tmp folder on the build system and its size is greater than 1024 bytes. - Note: The file can be stored in any location on the build system. The current SDK imlemnetstion stores the log file transferred using BDX protocol in /tmp folder. - disabled: true + Notes: + The file can be stored in any location on the build system. + The current SDK implementation stores log files transferred via the BDX protocol in the /tmp folder. + if {PICS_MCORE_DLOG_S_UTCTIMESTAMP} then verify that UTCTimeStamp is included in the RetrieveLogsResponse command + if {PICS_MCORE_DLOG_S_TIMESINCEBOOT} then verify that TimeSinceBoot is included in the RetrieveLogsResponse command - label: "Step 4: if (SendInitMsgfromDUT = false) TH does not send BDX SendAccept message to DUT" PICS: MCORE.BDX.Initiator verification: | - As SendInitMsgfromDUT = true this step is not applicable + If SendInitMsgfromDUT = false proceed with the following validation: + 1. Verification: + On TH(chip-tool), verify that the DUT responds by sending RetrieveLogsResponse Command with Exhausted(1) status code to TH and LogContent field of RetrieveLogsResponse contains at most 1024 bytes + + [1725363236.448] [56032:56034] [DMG] Received Command Response Data, Endpoint=0 Cluster=0x0000_0032 Command=0x0000_0001 + [1725363236.449] [56032:56034] [TOO] Endpoint: 0 Cluster: 0x0000_0032 Command 0x0000_0001 + [1725363236.449] [56032:56034] [TOO] RetrieveLogsResponse: { + [1725363236.449] [56032:56034] [TOO] status: 1 + [1725363236.449] [56032:56034] [TOO] logContent: 3132330A + [1725363236.449] [56032:56034] [TOO] } + + OR + + On TH(chip-tool), verify that the DUT responds by sending RetrieveLogsResponse Command with NoLogs(2) status code to TH and LogContent field is empty + + [1707967219.637228][10723:10726] CHIP:TOO: RetrieveLogsResponse: { + [1707967219.637242][10723:10726] CHIP:TOO: status: 2 + [1707967219.637248][10723:10726] CHIP:TOO: logContent: + [1707967219.637253][10723:10726] CHIP:TOO: } disabled: true - label: "Step 5: Repeat Steps from 2 to 4 by setting Intent field to NetworkDiag and CrashLogs" verification: | - + Repeat Steps from 2 to 4 by setting Intent field to + NetworkDiag CrashLogs as shown below in steps 2a to 4b disabled: true - label: @@ -129,8 +166,20 @@ tests: diagnosticlogs retrieve-logs-request 1 1 1 0 --TransferFileDesignator Length_123456789123456789123.txt - Note: nw_log does not exist and DUT does not initiate the BDX transfer - SendInitMsgfromDUT = false + If DUT sends SendInit message (BDX inititation happens from DUT) SendInitMsgfromDUT = true + + On TH(chip-tool), Verify that the DUT sends SendInit message with TransferFileDesignator field set to Length_123456789123456789123.txt + + 1707966626.594544][10635:10638] CHIP:ATM: SendInit + [1707966626.594550][10635:10638] CHIP:ATM: Proposed Transfer Control: 0x10 + [1707966626.594558][10635:10638] CHIP:ATM: Range Control: 0x0 + [1707966626.594563][10635:10638] CHIP:ATM: Proposed Max Block Size: 1024 + [1707966626.594569][10635:10638] CHIP:ATM: Start Offset: 0x0000000000000000 + [1707966626.594577][10635:10638] CHIP:ATM: Proposed Max Length: 0x0000000000000000 + [1707966626.594584][10635:10638] CHIP:ATM: File Designator Length: 32 + [1707966626.594588][10635:10638] CHIP:ATM: File Designator: Length_123456789123456789123.txt + + Else SendInitMsgfromDUT = false (DUT does not send SendInit message) disabled: true - label: @@ -138,7 +187,35 @@ tests: message to DUT" PICS: MCORE.BDX.Initiator verification: | - SendInitMsgfromDUT = false this step is not applicable + If SendInitMsgfromDUT = true proceed with the following validation: + + 1. Message Flow: + On chip-tool (TH): Send the SendAccept message to the DUT: + [1707894873.734698][34353:34356] CHIP:ATM: Sending BDX Message + [1707894873.734710][34353:34356] CHIP:ATM: SendAccept + [1707894873.734715][34353:34356] CHIP:ATM: Transfer Control: 0x10 + [1707894873.734720][34353:34356] CHIP:ATM: Max Block Size: 1024 + [1707894874.235405][34353:34356] CHIP:BDX: Got an event MsgToSend + + On TH (chip-tool): Verify that the DUT responds with the RetrieveLogsResponse command with a Success(0) status code and LogContent field is empty: + + 1707894874.239127][34353:34356] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_0032 Command 0x0000_0001 + [1707894874.239189][34353:34356] CHIP:TOO: RetrieveLogsResponse: { + [1707894874.239208][34353:34356] CHIP:TOO: status: 0 + [1707894874.239219][34353:34356] CHIP:TOO: logContent: + [1707894874.239227][34353:34356] CHIP:TOO: } + + 2. File Transfer Verification: + - Check the size of the file specified in the File Designator field of the RetrieveLogsRequest command. + - Confirm that the size is greater than 1024 bytes. + - Example file: Length_123456789123456789123.txt + - Verify that the file is transferred to the /tmp folder on the build system and its size is greater than 1024 bytes. + + Notes: + The file can be stored in any location on the build system. + The current SDK implementation stores log files transferred via the BDX protocol in the /tmp folder. + if {PICS_MCORE_DLOG_S_UTCTIMESTAMP} then verify that UTCTimeStamp is included in the RetrieveLogsResponse command + if {PICS_MCORE_DLOG_S_TIMESINCEBOOT} then verify that TimeSinceBoot is included in the RetrieveLogsResponse command disabled: true - label: @@ -146,6 +223,20 @@ tests: SendAccept message to DUT" PICS: MCORE.BDX.Initiator verification: | + If SendInitMsgfromDUT = false proceed with the following validation: + + 1. Verification: + On TH(chip-tool), verify that the DUT responds by sending RetrieveLogsResponse Command with Exhausted(1) status code to TH and LogContent field of RetrieveLogsResponse contains at most 1024 bytes + + [1725363236.448] [56032:56034] [DMG] Received Command Response Data, Endpoint=0 Cluster=0x0000_0032 Command=0x0000_0001 + [1725363236.449] [56032:56034] [TOO] Endpoint: 0 Cluster: 0x0000_0032 Command 0x0000_0001 + [1725363236.449] [56032:56034] [TOO] RetrieveLogsResponse: { + [1725363236.449] [56032:56034] [TOO] status: 1 + [1725363236.449] [56032:56034] [TOO] logContent: 3132330A + [1725363236.449] [56032:56034] [TOO] } + + OR + On TH(chip-tool), verify that the DUT responds by sending RetrieveLogsResponse Command with NoLogs(2) status code to TH and LogContent field is empty [1707967219.637228][10723:10726] CHIP:TOO: RetrieveLogsResponse: { @@ -165,8 +256,21 @@ tests: diagnosticlogs retrieve-logs-request 2 1 1 0 --TransferFileDesignator Length_123456789123456789123.txt - Note: crash_log < 1024 Bytes and DUT does not inittiate the BDX transfer - SendInitMsgfromDUT = false + If DUT sends SendInit message (BDX inititation happens from DUT) + SendInitMsgfromDUT = true + + On TH(chip-tool), Verify that the DUT sends SendInit message with TransferFileDesignator field set to Length_123456789123456789123.txt + + 1707966626.594544][10635:10638] CHIP:ATM: SendInit + [1707966626.594550][10635:10638] CHIP:ATM: Proposed Transfer Control: 0x10 + [1707966626.594558][10635:10638] CHIP:ATM: Range Control: 0x0 + [1707966626.594563][10635:10638] CHIP:ATM: Proposed Max Block Size: 1024 + [1707966626.594569][10635:10638] CHIP:ATM: Start Offset: 0x0000000000000000 + [1707966626.594577][10635:10638] CHIP:ATM: Proposed Max Length: 0x0000000000000000 + [1707966626.594584][10635:10638] CHIP:ATM: File Designator Length: 32 + [1707966626.594588][10635:10638] CHIP:ATM: File Designator: Length_123456789123456789123.txt + + Else SendInitMsgfromDUT = false (DUT does not send SendInit message) disabled: true - label: @@ -174,7 +278,36 @@ tests: message to DUT" PICS: MCORE.BDX.Initiator verification: | - SendInitMsgfromDUT = false this step is not applicable + If SendInitMsgfromDUT = true proceed with the following validation: + + 1. Message Flow: + On chip-tool (TH): Send the SendAccept message to the DUT: + + [1707894873.734698][34353:34356] CHIP:ATM: Sending BDX Message + [1707894873.734710][34353:34356] CHIP:ATM: SendAccept + [1707894873.734715][34353:34356] CHIP:ATM: Transfer Control: 0x10 + [1707894873.734720][34353:34356] CHIP:ATM: Max Block Size: 1024 + [1707894874.235405][34353:34356] CHIP:BDX: Got an event MsgToSend + + On TH (chip-tool): Verify that the DUT responds with the RetrieveLogsResponse command with a Success(0) status code and LogContent field is empty: + + 1707894874.239127][34353:34356] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_0032 Command 0x0000_0001 + [1707894874.239189][34353:34356] CHIP:TOO: RetrieveLogsResponse: { + [1707894874.239208][34353:34356] CHIP:TOO: status: 0 + [1707894874.239219][34353:34356] CHIP:TOO: logContent: + [1707894874.239227][34353:34356] CHIP:TOO: } + + 2. File Transfer Verification: + - Check the size of the file specified in the File Designator field of the RetrieveLogsRequest command. + - Confirm that the size is greater than 1024 bytes. + - Example file: Length_123456789123456789123.txt + - Verify that the file is transferred to the /tmp folder on the build system and its size is greater than 1024 bytes. + + Notes: + The file can be stored in any location on the build system. + The current SDK implementation stores log files transferred via the BDX protocol in the /tmp folder. + if {PICS_MCORE_DLOG_S_UTCTIMESTAMP} then verify that UTCTimeStamp is included in the RetrieveLogsResponse command + if {PICS_MCORE_DLOG_S_TIMESINCEBOOT} then verify that TimeSinceBoot is included in the RetrieveLogsResponse command disabled: true - label: @@ -182,14 +315,26 @@ tests: SendAccept message to DUT" PICS: MCORE.BDX.Initiator verification: | + If SendInitMsgfromDUT = false proceed with the following validation: + + 1. Verification: On TH(chip-tool), verify that the DUT responds by sending RetrieveLogsResponse Command with Exhausted(1) status code to TH and LogContent field of RetrieveLogsResponse contains at most 1024 bytes - 1707894938.009997][34371:34374] CHIP:TOO: RetrieveLogsResponse: { - [1707894938.010025][34371:34374] CHIP:TOO: status: 1 - [1707894938.010057][34371:34374] CHIP:TOO: logContent: RetrieveLogsResponse: { - [1707967525.484222][10866:10869] CHIP:TOO: status: 1 - [1707967525.484229][10866:10869] CHIP:TOO: logContent: 353535350A - [1707967525.484233][10866:10869] CHIP:TOO: } + [1725363236.448] [56032:56034] [DMG] Received Command Response Data, Endpoint=0 Cluster=0x0000_0032 Command=0x0000_0001 + [1725363236.449] [56032:56034] [TOO] Endpoint: 0 Cluster: 0x0000_0032 Command 0x0000_0001 + [1725363236.449] [56032:56034] [TOO] RetrieveLogsResponse: { + [1725363236.449] [56032:56034] [TOO] status: 1 + [1725363236.449] [56032:56034] [TOO] logContent: 3132330A + [1725363236.449] [56032:56034] [TOO] } + + OR + + On TH(chip-tool), verify that the DUT responds by sending RetrieveLogsResponse Command with NoLogs(2) status code to TH and LogContent field is empty + + [1707967219.637228][10723:10726] CHIP:TOO: RetrieveLogsResponse: { + [1707967219.637242][10723:10726] CHIP:TOO: status: 2 + [1707967219.637248][10723:10726] CHIP:TOO: logContent: + [1707967219.637253][10723:10726] CHIP:TOO: } disabled: true - label: @@ -201,7 +346,10 @@ tests: verification: | diagnosticlogs retrieve-logs-request 0 1 1 0 --TransferFileDesignator Length_1234567.txt - On TH(chip-tool), Verify that the DUT sends SendInit message with TransferFileDesignator field set to Length_1234567891234567891 + If DUT sends SendInit message (BDX inititation happens from DUT) + SendInitMsgfromDUT = true + + On TH(chip-tool), Verify that the DUT sends SendInit message with TransferFileDesignator field set to Length_1234567.txt [1707967645.770994][10882:10885] CHIP:ATM: SendInit [1707967645.770997][10882:10885] CHIP:ATM: Proposed Transfer Control: 0x10 [1707967645.771001][10882:10885] CHIP:ATM: Range Control: 0x0 @@ -211,8 +359,7 @@ tests: [1707967645.771014][10882:10885] CHIP:ATM: File Designator Length: 18 [1707967645.771018][10882:10885] CHIP:ATM: File Designator: Length_1234567.txt - Note: end_user_support_log > 1024 bytes so that BDX inititation happens from DUT - SendInitMsgfromDUT = true" + Else SendInitMsgfromDUT = false (DUT does not send SendInit message) disabled: true - label: @@ -221,7 +368,14 @@ tests: TH_LOG_ERROR_TRANSFER_METHOD_NOT_SUPPORTED) to DUT" PICS: MCORE.BDX.Initiator verification: | - Not Verifiable. This step requires additional API for error injection.(Not available in the Chip-tool) + Note : Not Verifiable. This step requires additional API for error injection.(Not available in the Chip-tool) + + if (SendInitMsgfromDUT = true) , On TH(chip-tool), verify that the DUT responds by sending RetrieveLogsResponse Command with Status field set to Denied(4) + + [1707967219.637228][10723:10726] CHIP:TOO: RetrieveLogsResponse: { + [1707967219.637242][10723:10726] CHIP:TOO: status: 4 + [1707967219.637248][10723:10726] CHIP:TOO: logContent: + [1707967219.637253][10723:10726] CHIP:TOO: } disabled: true - label: @@ -235,29 +389,23 @@ tests: On TH(chip-tool), Verify that the DUT responds with Success(0) status code for the RetrieveLogsResponse command Verify that LogContent field contains at most 1024 bytes + RetrieveLogsResponse: { [1707901602.742523][36080:36083] CHIP:TOO: status: 0 [1707901602.742542][36080:36083] CHIP:TOO: logContent: 31353238303033363031313533353030333730303234303030303234303133653234303230313138333530313331303034373032313533313031316230323330383230323137303630393261383634383836663730643031303730326130383230323038333038323032303430323031303333313064333030623036303936303836343830313635303330343032303133303832303137303036303932613836343838366637306430313037303161303832303136313034383230313564313532343030303132353031663166663336303230353030383030353031383030353032383030353033383030353034383030353035383030353036383030353037383030353038383030353039383030353061383030353062383030353063383030353064383030353065383030353066383030353130383030353131383030353132383030353133383030353134383030353135383030353136383030353137383030353138383030353139383030353161383030353162383030353163383030353164383030353165383030353166383030353230383030353231383030353232383030353233383030353234383030353235383030353236383030353237383030353238383030353239383030353261383030353262383030353263383030353264383030353265383030353266383030353330383030353331383030353332383030353333383030353334383030353335383030353336383030353337383030353338383030353339383030353361383030353362383030353363383030353364383030353365383030353366383030353430383030353431383030353432383030353433383030353434383030353435383030353436383030353437383030353438383030353439383030353461383030353462383030353463383030353464383030353465383030353466383030353530383030353531383030353532383030353533383030353534383030353535383030353536383030353537383030353538383030353539383030353561383030353562383030353563383030353564383030353565383030353566383030353630383030353631383030353632383030353633383031383234303331363263303431333433353334313330333033303330333035333537343333303330333033303330326433303330323430353030323430363030323430373031323430383030313833313763333037613032303130333830313466653334336639353939343737363362363165653435333931333133333834393466653637643865333030623036303936303836343830633733653461363039363038363438303630393630383634383036303936303836343830363039363038363438303630393630383634383036303936303836 - Repeat this setp by setting Intent filed to NetworkDiag - diagnosticlogs retrieve-logs-request 1 0 1 0 - - On TH(chip-tool), verify that the DUT responds with NoLogs(2) status code to TH for the RetrieveLogsResponse command and LogContent field is empty + else if DUT responds with NoLogs(2) status code verify that LogContent field is empty [1707967219.637228][10723:10726] CHIP:TOO: RetrieveLogsResponse: { [1707967219.637242][10723:10726] CHIP:TOO: status: 2 [1707967219.637248][10723:10726] CHIP:TOO: logContent: [1707967219.637253][10723:10726] CHIP:TOO: } - Repeat this setp by setting Intent filed to Crash_log - diagnosticlogs retrieve-logs-request 2 0 1 0 - - On TH(chip-tool), verify that the DUT responds with success(0) status code to TH for the RetrieveLogsResponse command and LogContent field of RetrieveLogsResponse contains at most 1024 bytes + Repeat this step by setting Intent field to NetworkDiag by giving following command : + diagnosticlogs retrieve-logs-request 1 0 1 0 - [1707982645.639415][11765:11767] CHIP:TOO: RetrieveLogsResponse: { - [1707982645.639457][11765:11767] CHIP:TOO: status: 0 - [1707982645.639489][11765:11767] CHIP:TOO: logContent: logContent: 353535350A - }" + Repeat this step by setting Intent field to CrashLogs by giving following command : + diagnosticlogs retrieve-logs-request 2 0 1 0 disabled: true - label: @@ -270,6 +418,7 @@ tests: On TH(chip-tool), Verify that the DUT responds with INVALID_COMMAND for the RetrieveLogsRequest that was sent without TransferFileDesignator + [1707924172.241489][42120:42123] CHIP:DMG: InvokeResponseIB = [1707924172.241494][42120:42123] CHIP:DMG: { [1707924172.241497][42120:42123] CHIP:DMG: CommandStatusIB = @@ -293,7 +442,7 @@ tests: [1707924172.241573][42120:42123] CHIP:DMG: ], [1707924172.241577][42120:42123] CHIP:DMG: [1707924172.241579][42120:42123] CHIP:DMG: InteractionModelRevision = 11 - [1707924172.241582][42120:42123] CHIP:DMG: }," + [1707924172.241582][42120:42123] CHIP:DMG: }, disabled: true - label: @@ -306,9 +455,18 @@ tests: On TH(chip-tool), Verify that the DUT responds with Exhausted(1) status code for the RetrieveLogsResponse command with the LogContent field containing at most 1024 bytes - [1707979121.749537][7593:7596] CHIP:TOO: RetrieveLogsResponse: { - [1707979121.749565][7593:7596] CHIP:TOO: status: 1 - [1707979121.749593][7593:7596] CHIP:TOO: logContent: 31353238303033363031313533353030333730303234303030303234303133653234303230313138333530313331303034373032313533313031316230323330383230323137303630393261383634383836663730643031303730326130383230323038333038323032303430323031303333313064333030623036303936303836343830313635303330343032303133303832303137303036303932613836343838366637306430313037303161303832303136313034383230313564313532343030303132353031663166663336303230353030383030353031383030353032383030353033383030353034383030353035383030353036383030353037383030353038383030353039383030353061383030353062383030353063383030353064383030353065383030353066383030353130383030353131383030353132383030353133383030353134383030353135383030353136383030353137383030353138383030353139383030353161383030353162383030353163383030353164383030353165383030353166383030353230383030353231383030353232383030353233383030353234383030353235383030353236383030353237383030353238383030353239383030353261383030353262383030353263383030353264383030353265383030353266383030353330383030353331383030353332383030353333383030353334383030353335383030353336383030353337383030353338383030353339383030353361383030353362383030353363383030353364383030353365383030353366383030353430383030353431383030353432383030353433383030353434383030353435383030353436383030353437383030353438383030353439383030353461383030353462383030353463383030353464383030353465383030353466383030353530383030353531383030353532383030353533383030353534383030353535383030353536383030353537383030353538383030353539383030353561383030353562383030353563383030353564383030353565383030353566383030353630383030353631383030353632383030353633383031383234303331363263303431333433353334313330333033303330333035333537343333303330333033303330326433303330323430353030323430363030323430373031323430383030313833313763333037613032303130333830313466653334336639353939343737363362363165653435333931333133333834393466653637643865333030623036303936303836343830633733653461363039363038363438303630393630383634383036303936303836343830363039363038363438303630393630383634383036303936303836}" + + RetrieveLogsResponse: { + [1707901602.742523][36080:36083] CHIP:TOO: status: 1 + [1707901602.742542][36080:36083] CHIP:TOO: logContent: 31353238303033363031313533353030333730303234303030303234303133653234303230313138333530313331303034373032313533313031316230323330383230323137303630393261383634383836663730643031303730326130383230323038333038323032303430323031303333313064333030623036303936303836343830313635303330343032303133303832303137303036303932613836343838366637306430313037303161303832303136313034383230313564313532343030303132353031663166663336303230353030383030353031383030353032383030353033383030353034383030353035383030353036383030353037383030353038383030353039383030353061383030353062383030353063383030353064383030353065383030353066383030353130383030353131383030353132383030353133383030353134383030353135383030353136383030353137383030353138383030353139383030353161383030353162383030353163383030353164383030353165383030353166383030353230383030353231383030353232383030353233383030353234383030353235383030353236383030353237383030353238383030353239383030353261383030353262383030353263383030353264383030353265383030353266383030353330383030353331383030353332383030353333383030353334383030353335383030353336383030353337383030353338383030353339383030353361383030353362383030353363383030353364383030353365383030353366383030353430383030353431383030353432383030353433383030353434383030353435383030353436383030353437383030353438383030353439383030353461383030353462383030353463383030353464383030353465383030353466383030353530383030353531383030353532383030353533383030353534383030353535383030353536383030353537383030353538383030353539383030353561383030353562383030353563383030353564383030353565383030353566383030353630383030353631383030353632383030353633383031383234303331363263303431333433353334313330333033303330333035333537343333303330333033303330326433303330323430353030323430363030323430373031323430383030313833313763333037613032303130333830313466653334336639353939343737363362363165653435333931333133333834393466653637643865333030623036303936303836343830633733653461363039363038363438303630393630383634383036303936303836343830363039363038363438303630393630383634383036303936303836 + + else if DUT responds with NoLogs(2) status code verify that LogContent field is empty + + [1707967219.637228][10723:10726] CHIP:TOO: RetrieveLogsResponse: { + [1707967219.637242][10723:10726] CHIP:TOO: status: 2 + [1707967219.637248][10723:10726] CHIP:TOO: logContent: + [1707967219.637253][10723:10726] CHIP:TOO: } + disabled: true - label: @@ -331,7 +489,9 @@ tests: Repeat this step by setting RequestedProtocol as ResponsePayload : diagnosticlogs retrieve-logs-request 3 1 1 0 --TransferFileDesignator Length_1234567.txt + On TH(chip-tool), Verify that the DUT responds with INVALID_COMMAND for the RetrieveLogsRequest that was sent invalid Intent(3) + [1707901794.468552][36124:36127] CHIP:DMG: StatusIB = [1707901794.468560][36124:36127] CHIP:DMG: { [1707901794.468569][36124:36127] CHIP:DMG: status = 0x85 (INVALID_COMMAND), @@ -374,7 +534,7 @@ tests: [1707901794.468608][36124:36127] CHIP:DMG: }, [1707901794.468619][36124:36127] CHIP:DMG: [1707901794.468624][36124:36127] CHIP:DMG: ], - [1707901794.468635][36124:36127] CHIP:DMG:" + [1707901794.468635][36124:36127] CHIP:DMG: disabled: true - label: @@ -385,7 +545,25 @@ tests: PICS: MCORE.BDX.Initiator verification: | diagnosticlogs retrieve-logs-request 0 1 1 0 --TransferFileDesignator '' - On TH(chip-tool), Verify that DUT sends RetrieveLogsResponse command to TH with Denied(4) status code. + + On TH(chip-tool), Verify that DUT sends RetrieveLogsResponse command to TH with with Exhausted(1) status code then verify that LogContent field contains at most 1024 bytes + + [1725363236.448] [56032:56034] [DMG] Received Command Response Data, Endpoint=0 Cluster=0x0000_0032 Command=0x0000_0001 + [1725363236.449] [56032:56034] [TOO] Endpoint: 0 Cluster: 0x0000_0032 Command 0x0000_0001 + [1725363236.449] [56032:56034] [TOO] RetrieveLogsResponse: { + [1725363236.449] [56032:56034] [TOO] status: 1 + [1725363236.449] [56032:56034] [TOO] logContent: 3132330A + [1725363236.449] [56032:56034] [TOO] } + + else if DUT responds with NoLogs(2) status code verify that LogContent field is empty + + [1707967219.637228][10723:10726] CHIP:TOO: RetrieveLogsResponse: { + [1707967219.637242][10723:10726] CHIP:TOO: status: 2 + [1707967219.637248][10723:10726] CHIP:TOO: logContent: + [1707967219.637253][10723:10726] CHIP:TOO: } + + else if DUT responds with NoLogs(4) status code verify that LogContent field is empty + [1719990173.360981][8053:8056] CHIP:TOO: RetrieveLogsResponse: { [1719990173.361009][8053:8056] CHIP:TOO: status: 4 [1719990173.361021][8053:8056] CHIP:TOO: logContent: @@ -400,7 +578,8 @@ tests: verification: | diagnosticlogs retrieve-logs-request 0 1 1 0 --TransferFileDesignator Length_1234567891234567891234567891212345.txt - On TH(chip-tool), Verify that the DUT responds with CONSTRAINT_ERROR for the RetrieveLogsRequest that was sent Invalid Invalid TransferFileDesignator length(> 32) + On TH(chip-tool), Verify that the DUT responds with CONSTRAINT_ERROR for the RetrieveLogsRequest that was sent Invalid TransferFileDesignator length(> 32) + [1707904517.151453][36678:36681] CHIP:DMG: ICR moving to [ResponseRe] [1707904517.151489][36678:36681] CHIP:DMG: InvokeResponseMessage = @@ -431,5 +610,5 @@ tests: [1707904517.151798][36678:36681] CHIP:DMG: ], [1707904517.151816][36678:36681] CHIP:DMG: [1707904517.151824][36678:36681] CHIP:DMG: InteractionModelRevision = 11 - [1707904517.151830][36678:36681] CHIP:DMG: }," + [1707904517.151830][36678:36681] CHIP:DMG: }, disabled: true From 35781e5852c6f319708502c1008545804bc6a0e4 Mon Sep 17 00:00:00 2001 From: Amine Alami <43780877+Alami-Amine@users.noreply.github.com> Date: Thu, 6 Feb 2025 18:55:54 +0100 Subject: [PATCH 09/39] [PSA] bugfix for potential buffer overflow from AES_CCM Encrypt/Decrypt (#37337) * [PSA] bugfix for potential buffer overflow from AES_CCM Encrypt/Decrypt * Integrating Comments * Integrating comments --- src/crypto/CHIPCryptoPALPSA.cpp | 93 +++++++++++++++++++++++++++++---- 1 file changed, 83 insertions(+), 10 deletions(-) diff --git a/src/crypto/CHIPCryptoPALPSA.cpp b/src/crypto/CHIPCryptoPALPSA.cpp index 924759b935..7aa33c1c66 100644 --- a/src/crypto/CHIPCryptoPALPSA.cpp +++ b/src/crypto/CHIPCryptoPALPSA.cpp @@ -72,8 +72,8 @@ CHIP_ERROR AES_CCM_encrypt(const uint8_t * plaintext, size_t plaintext_length, c const psa_algorithm_t algorithm = PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, tag_length); psa_status_t status = PSA_SUCCESS; psa_aead_operation_t operation = PSA_AEAD_OPERATION_INIT; - size_t out_length; - size_t tag_out_length; + size_t out_length = 0; + size_t tag_out_length = 0; status = psa_aead_encrypt_setup(&operation, key.As(), algorithm); VerifyOrReturnError(status == PSA_SUCCESS, CHIP_ERROR_INTERNAL); @@ -94,19 +94,58 @@ CHIP_ERROR AES_CCM_encrypt(const uint8_t * plaintext, size_t plaintext_length, c ChipLogDetail(Crypto, "AES_CCM_encrypt: Using aad == null path"); } - if (plaintext_length != 0) + // psa_aead_update() requires use of the macro PSA_AEAD_UPDATE_OUTPUT_SIZE to determine the output buffer size. + // For AES-CCM, PSA_AEAD_UPDATE_OUTPUT_SIZE will round up the size to the next multiple of the block size (16). + // If the ciphertext length is not a multiple of the block size, we will encrypt in two steps, first with the + // block_aligned_length, and then with a rounded up partial_block_length, where a temporary buffer will be used for the output. + constexpr uint8_t kBlockSize = PSA_BLOCK_CIPHER_BLOCK_LENGTH(PSA_KEY_TYPE_AES); + size_t block_aligned_length = (plaintext_length / kBlockSize) * kBlockSize; + size_t partial_block_length = plaintext_length % kBlockSize; + + // Make sure the calculated block_aligned_length is compliant with PSA's output size requirements. + VerifyOrReturnError(block_aligned_length == PSA_AEAD_UPDATE_OUTPUT_SIZE(PSA_KEY_TYPE_AES, algorithm, block_aligned_length), + CHIP_ERROR_INTERNAL); + + if (block_aligned_length > 0) { - status = psa_aead_update(&operation, plaintext, plaintext_length, ciphertext, - PSA_AEAD_UPDATE_OUTPUT_SIZE(PSA_KEY_TYPE_AES, algorithm, plaintext_length), &out_length); + status = psa_aead_update(&operation, plaintext, block_aligned_length, ciphertext, block_aligned_length, &out_length); VerifyOrReturnError(status == PSA_SUCCESS, CHIP_ERROR_INTERNAL); ciphertext += out_length; + } + + if (partial_block_length > 0) + { + uint8_t temp_buffer[kBlockSize]; + size_t rounded_up_length = PSA_AEAD_UPDATE_OUTPUT_SIZE(PSA_KEY_TYPE_AES, algorithm, partial_block_length); + + VerifyOrReturnError(rounded_up_length <= sizeof(temp_buffer), CHIP_ERROR_BUFFER_TOO_SMALL); + + out_length = 0; + status = psa_aead_update(&operation, plaintext + block_aligned_length, partial_block_length, &temp_buffer[0], + rounded_up_length, &out_length); + VerifyOrReturnError(status == PSA_SUCCESS, CHIP_ERROR_INTERNAL); + + VerifyOrReturnError(partial_block_length == out_length, CHIP_ERROR_INTERNAL); + memcpy(ciphertext, temp_buffer, partial_block_length); + + ciphertext += out_length; + } + + if (plaintext_length != 0) + { + out_length = 0; + tag_out_length = 0; status = psa_aead_finish(&operation, ciphertext, PSA_AEAD_FINISH_OUTPUT_SIZE(PSA_KEY_TYPE_AES, algorithm), &out_length, tag, tag_length, &tag_out_length); } + else { + out_length = 0; + tag_out_length = 0; + status = psa_aead_finish(&operation, nullptr, 0, &out_length, tag, tag_length, &tag_out_length); } VerifyOrReturnError(status == PSA_SUCCESS && tag_length == tag_out_length, CHIP_ERROR_INTERNAL); @@ -126,7 +165,7 @@ CHIP_ERROR AES_CCM_decrypt(const uint8_t * ciphertext, size_t ciphertext_length, const psa_algorithm_t algorithm = PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, tag_length); psa_status_t status = PSA_SUCCESS; psa_aead_operation_t operation = PSA_AEAD_OPERATION_INIT; - size_t outLength; + size_t outLength = 0; status = psa_aead_decrypt_setup(&operation, key.As(), algorithm); VerifyOrReturnError(status == PSA_SUCCESS, CHIP_ERROR_INTERNAL); @@ -147,20 +186,54 @@ CHIP_ERROR AES_CCM_decrypt(const uint8_t * ciphertext, size_t ciphertext_length, ChipLogDetail(Crypto, "AES_CCM_decrypt: Using aad == null path"); } - if (ciphertext_length != 0) + // psa_aead_update() requires use of the macro PSA_AEAD_UPDATE_OUTPUT_SIZE to determine the output buffer size. + // For AES-CCM, PSA_AEAD_UPDATE_OUTPUT_SIZE will round up the size to the next multiple of the block size (16). + // If the ciphertext length is not a multiple of the block size, we will decrypt in two steps, first with the + // block_aligned_length, and then with a rounded up partial_block_length, where a temporary buffer will be used for the output. + constexpr uint8_t kBlockSize = PSA_BLOCK_CIPHER_BLOCK_LENGTH(PSA_KEY_TYPE_AES); + size_t block_aligned_length = (ciphertext_length / kBlockSize) * kBlockSize; + size_t partial_block_length = ciphertext_length % kBlockSize; + + // Make sure the calculated block_aligned_length is compliant with PSA's output size requirements. + VerifyOrReturnError(block_aligned_length == PSA_AEAD_UPDATE_OUTPUT_SIZE(PSA_KEY_TYPE_AES, algorithm, block_aligned_length), + CHIP_ERROR_INTERNAL); + + if (block_aligned_length > 0) { - status = psa_aead_update(&operation, ciphertext, ciphertext_length, plaintext, - PSA_AEAD_UPDATE_OUTPUT_SIZE(PSA_KEY_TYPE_AES, algorithm, ciphertext_length), &outLength); + status = psa_aead_update(&operation, ciphertext, block_aligned_length, plaintext, block_aligned_length, &outLength); VerifyOrReturnError(status == PSA_SUCCESS, CHIP_ERROR_INTERNAL); plaintext += outLength; + } + + if (partial_block_length > 0) + { + uint8_t temp_buffer[kBlockSize]; + size_t rounded_up_length = PSA_AEAD_UPDATE_OUTPUT_SIZE(PSA_KEY_TYPE_AES, algorithm, partial_block_length); + + VerifyOrReturnError(rounded_up_length <= sizeof(temp_buffer), CHIP_ERROR_BUFFER_TOO_SMALL); + outLength = 0; + status = psa_aead_update(&operation, ciphertext + block_aligned_length, partial_block_length, &temp_buffer[0], + rounded_up_length, &outLength); + VerifyOrReturnError(status == PSA_SUCCESS, CHIP_ERROR_INTERNAL); + + VerifyOrReturnError(partial_block_length == outLength, CHIP_ERROR_INTERNAL); + memcpy(plaintext, &temp_buffer[0], partial_block_length); + + plaintext += outLength; + } + + if (ciphertext_length != 0) + { + outLength = 0; status = psa_aead_verify(&operation, plaintext, PSA_AEAD_VERIFY_OUTPUT_SIZE(PSA_KEY_TYPE_AES, algorithm), &outLength, tag, tag_length); } else { - status = psa_aead_verify(&operation, nullptr, 0, &outLength, tag, tag_length); + outLength = 0; + status = psa_aead_verify(&operation, nullptr, 0, &outLength, tag, tag_length); } VerifyOrReturnError(status == PSA_SUCCESS, CHIP_ERROR_INTERNAL); From 2cf6dd8ad96b4a017a9eb5d0e094cded6191d706 Mon Sep 17 00:00:00 2001 From: Jeff Tung <100387939+jtung-apple@users.noreply.github.com> Date: Thu, 6 Feb 2025 11:38:53 -0800 Subject: [PATCH 10/39] [Darwin] MTRDevice should tear down subscription on dealloc (#37418) * [Darwin] MTRDevice should tear down subscription on dealloc * Update src/darwin/Framework/CHIP/MTRDevice_Concrete.mm Co-authored-by: Boris Zbarsky * Update src/darwin/Framework/CHIP/MTRDevice_Concrete.mm Co-authored-by: Boris Zbarsky * Fix log line. * Make sure that _persistClusterData only notifies delegates when persistence actually happens. * Fix unit test to wait for delete properly --------- Co-authored-by: Boris Zbarsky Co-authored-by: Justin Wood --- .../Framework/CHIP/MTRDevice_Concrete.mm | 340 +++++++++++++++--- .../CHIPTests/MTRPerControllerStorageTests.m | 81 +++++ .../TestHelpers/MTRDeviceTestDelegate.h | 2 + .../TestHelpers/MTRDeviceTestDelegate.m | 14 + 4 files changed, 392 insertions(+), 45 deletions(-) diff --git a/src/darwin/Framework/CHIP/MTRDevice_Concrete.mm b/src/darwin/Framework/CHIP/MTRDevice_Concrete.mm index 0434f4890c..2a9ef219ee 100644 --- a/src/darwin/Framework/CHIP/MTRDevice_Concrete.mm +++ b/src/darwin/Framework/CHIP/MTRDevice_Concrete.mm @@ -131,6 +131,67 @@ - (void)_deviceInternalStateChanged:(MTRDevice *)device; } // anonymous namespace +#pragma mark - MTRDeviceMatterCPPObjectsHolder + +// Class to hold C++ objects that can only be manipulated on the Matter queue +@interface MTRDeviceMatterCPPObjectsHolder : NSObject +@property (nonatomic, readonly) ReadClient * readClient; +@property (nonatomic, readonly) SubscriptionCallback * subscriptionCallback; // valid when and only when readClient is valid +- (void)setReadClient:(ReadClient * _Nullable)readClient subscriptionCallback:(SubscriptionCallback * _Nullable)subscriptionCallback; +- (void)clearReadClientAndDeleteSubscriptionCallback; +@end + +@implementation MTRDeviceMatterCPPObjectsHolder +@synthesize readClient = _readClient; +@synthesize subscriptionCallback = _subscriptionCallback; +- (ReadClient *)readClient +{ + assertChipStackLockedByCurrentThread(); + @synchronized(self) { + return _readClient; + } +} +- (SubscriptionCallback *)subscriptionCallback +{ + assertChipStackLockedByCurrentThread(); + @synchronized(self) { + return _subscriptionCallback; + } +} +- (void)setReadClient:(ReadClient * _Nullable)readClient subscriptionCallback:(SubscriptionCallback * _Nullable)subscriptionCallback +{ + assertChipStackLockedByCurrentThread(); + @synchronized(self) { + // Sanity check and log if readClient and subscriptionCallback aren't both valid or both null + if (((readClient == nullptr) && (subscriptionCallback != nullptr)) || ((readClient != nullptr) && (subscriptionCallback == nullptr))) { + MTR_LOG_ERROR("%@: setReadClient:subscriptionCallback: readClient and subscriptionCallback must both be valid or both be null %p %p", self, readClient, subscriptionCallback); + } + + // Sanity check and log if overriding existing values + if ((readClient != nullptr) && (_readClient != nullptr)) { + MTR_LOG_ERROR("%@: setReadClient:subscriptionCallback: readClient set when current value not null %p %p", self, readClient, _readClient); + } + if (((subscriptionCallback != nullptr)) && (_subscriptionCallback != nullptr)) { + MTR_LOG_ERROR("%@: setReadClient:subscriptionCallback: subscriptionCallback set when current value not null %p %p", self, subscriptionCallback, _subscriptionCallback); + } + + _readClient = readClient; + _subscriptionCallback = subscriptionCallback; + } +} +- (void)clearReadClientAndDeleteSubscriptionCallback +{ + assertChipStackLockedByCurrentThread(); + @synchronized(self) { + _readClient = nullptr; + if (_subscriptionCallback) { + delete _subscriptionCallback; + _subscriptionCallback = nullptr; + } + } +} +@end + #pragma mark - MTRDevice // Utility methods for working with MTRInternalDeviceState, located near the @@ -275,14 +336,14 @@ @interface MTRDevice_Concrete () * called SendAutoResubscribeRequest on the ReadClient and have not yet gotten * an OnDone for that ReadClient. */ -@property (nonatomic) ReadClient * currentReadClient; -@property (nonatomic) SubscriptionCallback * currentSubscriptionCallback; // valid when and only when currentReadClient is valid +@property (nonatomic, readonly) MTRDeviceMatterCPPObjectsHolder * matterCPPObjectsHolder; @end // Declaring selector so compiler won't complain about testing and calling it in _handleReportEnd #ifdef DEBUG @protocol MTRDeviceUnitTestDelegate +- (void)unitTestReportBeginForDevice:(MTRDevice *)device; - (void)unitTestReportEndForDevice:(MTRDevice *)device; - (BOOL)unitTestShouldSetUpSubscriptionForDevice:(MTRDevice *)device; - (BOOL)unitTestShouldSkipExpectedValuesForWrite:(MTRDevice *)device; @@ -293,6 +354,7 @@ - (void)unitTestSubscriptionPoolDequeue:(MTRDevice *)device; - (void)unitTestSubscriptionPoolWorkComplete:(MTRDevice *)device; - (void)unitTestClusterDataPersisted:(MTRDevice *)device; - (BOOL)unitTestSuppressTimeBasedReachabilityChanges:(MTRDevice *)device; +- (void)unitTestSubscriptionCallbackDeleteForDevice:(MTRDevice *)device; @end #endif @@ -407,6 +469,7 @@ - (instancetype)initWithNodeID:(NSNumber *)nodeID controller:(MTRDeviceControlle _clusterDataToPersist = nil; _persistedClusters = [NSMutableSet set]; _highestObservedEventNumber = nil; + _matterCPPObjectsHolder = [[MTRDeviceMatterCPPObjectsHolder alloc] init]; // If there is a data store, make sure we have an observer to monitor system clock changes, so // NSDate-based write coalescing could be reset and not get into a bad state. @@ -414,7 +477,7 @@ - (instancetype)initWithNodeID:(NSNumber *)nodeID controller:(MTRDeviceControlle mtr_weakify(self); _systemTimeChangeObserverToken = [[NSNotificationCenter defaultCenter] addObserverForName:NSSystemClockDidChangeNotification object:nil queue:nil usingBlock:^(NSNotification * _Nonnull notification) { mtr_strongify(self); - VerifyOrReturn(self); + VerifyOrReturn(self, MTR_LOG_DEBUG("NSNotificationCenter addObserverForName called back with nil MTRDevice")); std::lock_guard lock(self->_lock); [self _resetStorageBehaviorState]; @@ -430,10 +493,36 @@ - (instancetype)initWithNodeID:(NSNumber *)nodeID controller:(MTRDeviceControlle - (void)dealloc { + MTR_LOG("MTRDevice dealloc: %p", self); + [[NSNotificationCenter defaultCenter] removeObserver:_systemTimeChangeObserverToken]; - // TODO: retain cycle and clean up https://github.com/project-chip/connectedhomeip/issues/34267 - MTR_LOG("MTRDevice dealloc: %p", self); +#ifdef DEBUG + // Save the first delegate for testing + __block id testDelegate = nil; + for (MTRDeviceDelegateInfo * delegateInfo in _delegates) { + testDelegate = delegateInfo.delegate; + break; + } +#endif + [_delegates removeAllObjects]; + + // Delete subscription callback object to tear down ReadClient + MTRDeviceMatterCPPObjectsHolder * matterCPPObjectsHolder = self.matterCPPObjectsHolder; + [self._concreteController asyncDispatchToMatterQueue:^{ + [matterCPPObjectsHolder clearReadClientAndDeleteSubscriptionCallback]; +#ifdef DEBUG + // tell test delegate about having completed the deletion + if ([testDelegate respondsToSelector:@selector(unitTestSubscriptionCallbackDeleteForDevice:)]) { + [testDelegate unitTestSubscriptionCallbackDeleteForDevice:nil]; + } +#endif + } errorHandler:nil]; + + // Clear this device from subscription pool and persist cached data to storage as needed. + std::lock_guard lock(_lock); + [self _clearSubscriptionPoolWork]; + [self _doPersistClusterData]; } - (NSString *)description @@ -683,7 +772,9 @@ - (void)_setUTCTime:(UInt64)matterEpochTime withGranularity:(uint8_t)granularity alloc] init]; params.utcTime = @(matterEpochTime); params.granularity = @(granularity); + mtr_weakify(self); auto setUTCTimeResponseHandler = ^(id _Nullable response, NSError * _Nullable error) { + mtr_strongify(self); if (error) { MTR_LOG_ERROR("%@ _setUTCTime failed on endpoint %@, with parameters %@, error: %@", self, endpoint, params, error); } @@ -711,7 +802,9 @@ - (void)_setDSTOffsets:(NSArray alloc] init]; params.dstOffset = dstOffsets; + mtr_weakify(self); auto setDSTOffsetResponseHandler = ^(id _Nullable response, NSError * _Nullable error) { + mtr_strongify(self); if (error) { MTR_LOG_ERROR("%@ _setDSTOffsets failed on endpoint %@, with parameters %@, error: %@", self, endpoint, params, error); } @@ -811,18 +904,24 @@ - (void)_ensureSubscriptionForExistingDelegates:(NSString *)reason if (!_initialSubscribeStart) { _initialSubscribeStart = [NSDate now]; } + mtr_weakify(self); if ([self _deviceUsesThread]) { MTR_LOG(" => %@ - device is a thread device, scheduling in pool", self); - mtr_weakify(self); NSString * description = [NSString stringWithFormat:@"MTRDevice setDelegate first subscription / controller resume (%p)", self]; [self _scheduleSubscriptionPoolWork:^{ mtr_strongify(self); - VerifyOrReturn(self); + VerifyOrReturn(self, MTR_LOG_DEBUG("_ensureSubscriptionForExistingDelegates _scheduleSubscriptionPoolWork called back with nil MTRDevice")); [self->_deviceController asyncDispatchToMatterQueue:^{ + mtr_strongify(self); + VerifyOrReturn(self, MTR_LOG_DEBUG("_ensureSubscriptionForExistingDelegates asyncDispatchToMatterQueue called back with nil MTRDevice")); + std::lock_guard lock(self->_lock); [self _setupSubscriptionWithReason:[NSString stringWithFormat:@"%@ and scheduled subscription is happening", reason]]; } errorHandler:^(NSError * _Nonnull error) { + mtr_strongify(self); + VerifyOrReturn(self, MTR_LOG_DEBUG("_ensureSubscriptionForExistingDelegates asyncDispatchToMatterQueue errored with nil MTRDevice")); + // If controller is not running, clear work item from the subscription queue MTR_LOG_ERROR("%@ could not dispatch to matter queue for resubscription - error %@", self, error); std::lock_guard lock(self->_lock); @@ -831,6 +930,9 @@ - (void)_ensureSubscriptionForExistingDelegates:(NSString *)reason } inNanoseconds:0 description:description]; } else { [_deviceController asyncDispatchToMatterQueue:^{ + mtr_strongify(self); + VerifyOrReturn(self, MTR_LOG_DEBUG("_ensureSubscriptionForExistingDelegates asyncDispatchToMatterQueue called back with nil MTRDevice")); + std::lock_guard lock(self->_lock); [self _setupSubscriptionWithReason:[NSString stringWithFormat:@"%@ and subscription is needed", reason]]; } errorHandler:nil]; @@ -863,7 +965,11 @@ - (void)invalidate // taking up a slot in the controller's work queue. [self _clearSubscriptionPoolWork]; + mtr_weakify(self); [_deviceController asyncDispatchToMatterQueue:^{ + mtr_strongify(self); + VerifyOrReturn(self, MTR_LOG_DEBUG("invalidate asyncDispatchToMatterQueue called back with nil MTRDevice")); + MTR_LOG("%@ invalidate disconnecting ReadClient and SubscriptionCallback", self); // Destroy the read client and callback (has to happen on the Matter @@ -917,8 +1023,8 @@ - (void)_triggerResubscribeWithReason:(NSString *)reason nodeLikelyReachable:(BO if (self.reattemptingSubscription) { [self _reattemptSubscriptionNowIfNeededWithReason:reason]; } else { - readClientToResubscribe = self->_currentReadClient; - subscriptionCallback = self->_currentSubscriptionCallback; + readClientToResubscribe = self.matterCPPObjectsHolder.readClient; + subscriptionCallback = self.matterCPPObjectsHolder.subscriptionCallback; } os_unfair_lock_unlock(&self->_lock); @@ -934,7 +1040,11 @@ - (void)_triggerResubscribeWithReason:(NSString *)reason nodeLikelyReachable:(BO } else if (_internalDeviceState == MTRInternalDeviceStateSubscribing && nodeLikelyReachable) { // If we have reason to suspect that the node is now reachable and we haven't established a // CASE session yet, let's consider it to be stalled and invalidate the pairing session. + mtr_weakify(self); [self._concreteController asyncGetCommissionerOnMatterQueue:^(Controller::DeviceCommissioner * commissioner) { + mtr_strongify(self); + VerifyOrReturn(self, MTR_LOG_DEBUG("_triggerResubscribeWithReason asyncGetCommissionerOnMatterQueue called back with nil MTRDevice")); + auto caseSessionMgr = commissioner->CASESessionMgr(); VerifyOrDie(caseSessionMgr != nullptr); caseSessionMgr->ReleaseSession(commissioner->GetPeerScopedId(self->_nodeID.unsignedLongLongValue)); @@ -1006,7 +1116,11 @@ - (void)_readThroughSkipped // Do the remaining work on the Matter queue, because we may want to touch // ReadClient in there. If the dispatch fails, that's fine; it means our // controller has shut down, so nothing to be done. + mtr_weakify(self); [_deviceController asyncDispatchToMatterQueue:^{ + mtr_strongify(self); + VerifyOrReturn(self, MTR_LOG_DEBUG("_readThroughSkipped asyncDispatchToMatterQueue called back with nil MTRDevice")); + [self _triggerResubscribeWithReason:@"read-through skipped while not subscribed" nodeLikelyReachable:NO]; } errorHandler:nil]; @@ -1245,18 +1359,19 @@ - (void)_scheduleSubscriptionPoolWork:(dispatch_block_t)workBlock inNanoseconds: mtr_strongify(self); // This block may be delayed by a specified number of nanoseconds, potentially running after the device is deallocated. // If so, MTRAsyncWorkItem::initWithQueue will assert on a nil queue, which will cause a crash. - VerifyOrReturn(self); + VerifyOrReturn(self, MTR_LOG_DEBUG("_scheduleSubscriptionPoolWork workBlockToQueue called with nil MTRDevice")); // In the case where a resubscription triggering event happened and already established, running the work block should result in a no-op MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.queue]; [workItem setReadyHandler:^(id _Nonnull context, NSInteger retryCount, MTRAsyncWorkCompletionBlock _Nonnull completion) { mtr_strongify(self); - VerifyOrReturn(self); + VerifyOrReturn(self, MTR_LOG_DEBUG("_scheduleSubscriptionPoolWork readyHandler called with nil MTRDevice")); MTR_LOG("%@ - work item is ready to attempt pooled subscription", self); os_unfair_lock_lock(&self->_lock); #ifdef DEBUG [self _callDelegatesWithBlock:^(id testDelegate) { + mtr_strongify(self); if ([testDelegate respondsToSelector:@selector(unitTestSubscriptionPoolDequeue:)]) { [testDelegate unitTestSubscriptionPoolDequeue:self]; } @@ -1307,7 +1422,11 @@ - (void)_handleResubscriptionNeededWithDelay:(NSNumber *)resubscriptionDelayMs [self _changeInternalState:MTRInternalDeviceStateResubscribing]; } + mtr_weakify(self); dispatch_async(self.queue, ^{ + mtr_strongify(self); + VerifyOrReturn(self, MTR_LOG_DEBUG("_handleResubscriptionNeededWithDelay async to self.queue with nil MTRDevice")); + [self _handleResubscriptionNeededWithDelayOnDeviceQueue:resubscriptionDelayMs]; }); } @@ -1338,11 +1457,17 @@ - (void)_handleResubscriptionNeededWithDelayOnDeviceQueue:(NSNumber *)resubscrip mtr_weakify(self); auto resubscriptionBlock = ^{ mtr_strongify(self); - VerifyOrReturn(self); + VerifyOrReturn(self, MTR_LOG_DEBUG("_handleResubscriptionNeededWithDelayOnDeviceQueue resubscriptionBlock called with nil MTRDevice")); [self->_deviceController asyncDispatchToMatterQueue:^{ + mtr_strongify(self); + VerifyOrReturn(self, MTR_LOG_DEBUG("_handleResubscriptionNeededWithDelayOnDeviceQueue resubscriptionBlock asyncDispatchToMatterQueue called back with nil MTRDevice")); + [self _triggerResubscribeWithReason:@"ResubscriptionNeeded timer fired" nodeLikelyReachable:NO]; } errorHandler:^(NSError * _Nonnull error) { + mtr_strongify(self); + VerifyOrReturn(self, MTR_LOG_DEBUG("_handleResubscriptionNeededWithDelayOnDeviceQueue resubscriptionBlock asyncDispatchToMatterQueue errored with nil MTRDevice")); + // If controller is not running, clear work item from the subscription queue MTR_LOG_ERROR("%@ could not dispatch to matter queue for resubscription - error %@", self, error); std::lock_guard lock(self->_lock); @@ -1455,13 +1580,19 @@ - (void)_doHandleSubscriptionReset:(NSNumber * _Nullable)retryDelay mtr_weakify(self); auto resubscriptionBlock = ^{ mtr_strongify(self); - VerifyOrReturn(self); + VerifyOrReturn(self, MTR_LOG_DEBUG("_doHandleSubscriptionReset resubscriptionBlock called with nil MTRDevice")); [self->_deviceController asyncDispatchToMatterQueue:^{ + mtr_strongify(self); + VerifyOrReturn(self, MTR_LOG_DEBUG("_doHandleSubscriptionReset resubscriptionBlock asyncDispatchToMatterQueue called back with nil MTRDevice")); + std::lock_guard lock(self->_lock); [self _reattemptSubscriptionNowIfNeededWithReason:@"got subscription reset"]; } errorHandler:^(NSError * _Nonnull error) { + mtr_strongify(self); + VerifyOrReturn(self, MTR_LOG_DEBUG("_doHandleSubscriptionReset resubscriptionBlock asyncDispatchToMatterQueue errored with nil MTRDevice")); + // If controller is not running, clear work item from the subscription queue MTR_LOG_ERROR("%@ could not dispatch to matter queue for resubscription - error %@", self, error); std::lock_guard lock(self->_lock); @@ -1520,7 +1651,11 @@ - (void)_handleUnsolicitedMessageFromPublisher - (void)_markDeviceAsUnreachableIfNeverSubscribed { + mtr_weakify(self); [_deviceController asyncDispatchToMatterQueue:^{ + mtr_strongify(self); + VerifyOrReturn(self, MTR_LOG_DEBUG("_markDeviceAsUnreachableIfNeverSubscribed asyncDispatchToMatterQueue called back with nil MTRDevice")); + std::lock_guard lock(self->_lock); if (HadSubscriptionEstablishedOnce(self->_internalDeviceState)) { @@ -1547,6 +1682,15 @@ - (void)_handleReportBegin // If we currently don't have an established subscription, this must be a // priming report. _receivingPrimingReport = !HaveSubscriptionEstablishedRightNow(_internalDeviceState); + + // For unit testing only +#ifdef DEBUG + [self _callDelegatesWithBlock:^(id testDelegate) { + if ([testDelegate respondsToSelector:@selector(unitTestReportBeginForDevice:)]) { + [testDelegate unitTestReportBeginForDevice:self]; + } + }]; +#endif } - (NSDictionary *)_clusterDataToPersistSnapshot @@ -1576,19 +1720,22 @@ - (BOOL)_dataStoreExists return _persistedClusterData != nil; } -- (void)_persistClusterData +// Need an inner method for dealloc to call, so unit test callbacks don't re-capture self. +// +// Returns whether persistence actually happened. +- (BOOL)_doPersistClusterData { os_unfair_lock_assert_owner(&self->_lock); // Sanity check if (![self _dataStoreExists]) { MTR_LOG_ERROR("%@ storage behavior: no data store in _persistClusterData!", self); - return; + return NO; } // Nothing to persist if (!_clusterDataToPersist.count) { - return; + return NO; } MTR_LOG("%@ Storing cluster information (data version and attributes) count: %lu", self, static_cast(_clusterDataToPersist.count)); @@ -1613,6 +1760,16 @@ - (void)_persistClusterData // to be sent to us via the priming read. _clusterDataToPersist = nil; + return YES; +} + +- (void)_persistClusterData +{ + if ([self _doPersistClusterData] == NO) { + // Don't notify delegates if we did not actually persist anything. + return; + } + #ifdef DEBUG [self _callDelegatesWithBlock:^(id testDelegate) { if ([testDelegate respondsToSelector:@selector(unitTestClusterDataPersisted:)]) { @@ -1797,7 +1954,11 @@ - (void)_scheduleClusterDataPersistence return; } + mtr_weakify(self); dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t) ([self _reportToPersistenceDelayTimeAfterMutiplier] * NSEC_PER_SEC)), self.queue, ^{ + mtr_strongify(self); + VerifyOrReturn(self, MTR_LOG_DEBUG("_scheduleClusterDataPersistence delayed store block called with nil MTRDevice")); + [self _persistClusterDataAsNeeded]; }); } @@ -1977,10 +2138,17 @@ - (void)_injectAttributeReport:(NSArray *)attr return; } + mtr_weakify(self); [_deviceController asyncDispatchToMatterQueue:^{ + mtr_strongify(self); + VerifyOrReturn(self, MTR_LOG_DEBUG("_injectAttributeReport asyncDispatchToMatterQueue called back with nil MTRDevice")); + MTR_LOG("%@ injected attribute report (%p) %@", self, attributeReport, attributeReport); [self _handleReportBegin]; dispatch_async(self.queue, ^{ + mtr_strongify(self); + VerifyOrReturn(self, MTR_LOG_DEBUG("_injectAttributeReport async to self.queue with nil MTRDevice")); + [self _handleAttributeReport:attributeReport fromSubscription:isFromSubscription]; [self _handleReportEnd]; }); @@ -1999,7 +2167,11 @@ - (void)_injectEventReport:(NSArray *)eventRep - (void)_injectPossiblyInvalidEventReport:(NSArray *)eventReport { + mtr_weakify(self); dispatch_async(self.queue, ^{ + mtr_strongify(self); + VerifyOrReturn(self, MTR_LOG_DEBUG("_injectPossiblyInvalidEventReport async to self.queue with nil MTRDevice")); + [self _handleEventReport:eventReport]; }); } @@ -2400,7 +2572,10 @@ - (void)_setupConnectivityMonitoring #if ENABLE_CONNECTIVITY_MONITORING // Dispatch to own queue because we used to need to do that to get the compressedFabricID, but // at this point that's not really needed anymore. + mtr_weakify(self); dispatch_async(self.queue, ^{ + mtr_strongify(self); + VerifyOrReturn(self, MTR_LOG_DEBUG("_setupConnectivityMonitoring dispatch to device queue called back with nil MTRDevice")); // Get the required info before setting up the connectivity monitor NSNumber * compressedFabricID = [self->_deviceController compressedFabricID]; if (!compressedFabricID) { @@ -2417,7 +2592,11 @@ - (void)_setupConnectivityMonitoring self->_connectivityMonitor = [[MTRDeviceConnectivityMonitor alloc] initWithCompressedFabricID:compressedFabricID nodeID:self.nodeID]; [self->_connectivityMonitor startMonitoringWithHandler:^{ + mtr_strongify(self); + VerifyOrReturn(self, MTR_LOG_DEBUG("_setupConnectivityMonitoring startMonitoringWithHandler called back with nil MTRDevice")); [self->_deviceController asyncDispatchToMatterQueue:^{ + mtr_strongify(self); + VerifyOrReturn(self, MTR_LOG_DEBUG("_setupConnectivityMonitoring asyncDispatchToMatterQueue called back with nil MTRDevice")); [self _triggerResubscribeWithReason:@"device connectivity changed" nodeLikelyReachable:YES]; } errorHandler:nil]; @@ -2441,7 +2620,11 @@ - (void)_resetSubscriptionWithReasonString:(NSString *)reasonString os_unfair_lock_assert_owner(&self->_lock); MTR_LOG_ERROR("%@ %@ - resetting subscription", self, reasonString); + mtr_weakify(self); [_deviceController asyncDispatchToMatterQueue:^{ + mtr_strongify(self); + VerifyOrReturn(self, MTR_LOG_DEBUG("_resetSubscriptionWithReasonString asyncDispatchToMatterQueue called back with nil MTRDevice")); + MTR_LOG("%@ subscription reset disconnecting ReadClient and SubscriptionCallback", self); std::lock_guard lock(self->_lock); @@ -2459,11 +2642,7 @@ - (void)_resetSubscription assertChipStackLockedByCurrentThread(); os_unfair_lock_assert_owner(&_lock); - _currentReadClient = nullptr; - if (_currentSubscriptionCallback) { - delete _currentSubscriptionCallback; - _currentSubscriptionCallback = nullptr; - } + [self.matterCPPObjectsHolder clearReadClientAndDeleteSubscriptionCallback]; [self _doHandleSubscriptionError:nil]; } @@ -2531,7 +2710,7 @@ - (void)_setupSubscriptionWithReason:(NSString *)reason mtr_weakify(self); dispatch_after(dispatch_time(DISPATCH_TIME_NOW, static_cast(kSecondsToWaitBeforeMarkingUnreachableAfterSettingUpSubscription) * static_cast(NSEC_PER_SEC)), self.queue, ^{ mtr_strongify(self); - VerifyOrReturn(self); + VerifyOrReturn(self, MTR_LOG_DEBUG("_setupSubscriptionWithReason markUnreachableAfterWait called back with nil MTRDevice")); if (!HaveSubscriptionEstablishedRightNow(self->_internalDeviceState)) { [self _markDeviceAsUnreachableIfNeverSubscribed]; @@ -2543,15 +2722,24 @@ - (void)_setupSubscriptionWithReason:(NSString *)reason // up the subscription since it is always retried as long as the MTRDevice is kept running. MATTER_LOG_METRIC_BEGIN(kMetricMTRDeviceInitialSubscriptionSetup); + // Reference the object holder directly + auto matterCPPObjectsHolder = self.matterCPPObjectsHolder; // Call directlyGetSessionForNode because the subscription setup already goes through the subscription pool queue + mtr_weakify(self); [self._concreteController directlyGetSessionForNode:_nodeID.unsignedLongLongValue completion:^(chip::Messaging::ExchangeManager * _Nullable exchangeManager, const chip::Optional & session, NSError * _Nullable error, NSNumber * _Nullable retryDelay) { + mtr_strongify(self); + VerifyOrReturn(self, MTR_LOG_DEBUG("_setupSubscriptionWithReason directlyGetSessionForNode called back with nil MTRDevice")); + if (error != nil) { MTR_LOG_ERROR("%@ getSessionForNode error %@", self, error); [self->_deviceController asyncDispatchToMatterQueue:^{ + mtr_strongify(self); + VerifyOrReturn(self, MTR_LOG_DEBUG("_setupSubscriptionWithReason asyncDispatchToMatterQueue called back with nil MTRDevice")); + [self _handleSubscriptionError:error]; [self _handleSubscriptionReset:retryDelay]; } errorHandler:nil]; @@ -2560,8 +2748,14 @@ - (void)_setupSubscriptionWithReason:(NSString *)reason auto callback = std::make_unique( ^(NSArray * value) { + mtr_strongify(self); + VerifyOrReturn(self, MTR_LOG_DEBUG("_setupSubscriptionWithReason subscription attribute report called back with nil MTRDevice")); + MTR_LOG("%@ got attribute report (%p) %@", self, value, value); dispatch_async(self.queue, ^{ + mtr_strongify(self); + VerifyOrReturn(self, MTR_LOG_DEBUG("_setupSubscriptionWithReason subscription attribute report async to device queue called back with nil MTRDevice")); + // OnAttributeData [self _handleAttributeReport:value fromSubscription:YES]; #ifdef DEBUG @@ -2570,23 +2764,38 @@ - (void)_setupSubscriptionWithReason:(NSString *)reason }); }, ^(NSArray * value) { + mtr_strongify(self); + VerifyOrReturn(self, MTR_LOG_DEBUG("_setupSubscriptionWithReason subscription event report called back with nil MTRDevice")); + MTR_LOG("%@ got event report %@", self, value); dispatch_async(self.queue, ^{ + mtr_strongify(self); + VerifyOrReturn(self, MTR_LOG_DEBUG("_setupSubscriptionWithReason subscription event report async to device queue called back with nil MTRDevice")); + // OnEventReport [self _handleEventReport:value]; }); }, ^(NSError * error) { + mtr_strongify(self); + VerifyOrReturn(self, MTR_LOG_DEBUG("_setupSubscriptionWithReason subscription error called back with nil MTRDevice")); + MTR_LOG_ERROR("%@ got subscription error %@", self, error); // OnError [self _handleSubscriptionError:error]; }, ^(NSError * error, NSNumber * resubscriptionDelayMs) { + mtr_strongify(self); + VerifyOrReturn(self, MTR_LOG_DEBUG("_setupSubscriptionWithReason subscription resubscription needed called back with nil MTRDevice")); + MTR_LOG_ERROR("%@ got resubscription error %@ delay %@", self, error, resubscriptionDelayMs); // OnResubscriptionNeeded [self _handleResubscriptionNeededWithDelay:resubscriptionDelayMs]; }, ^(void) { + mtr_strongify(self); + VerifyOrReturn(self, MTR_LOG_DEBUG("_setupSubscriptionWithReason subscription established called back with nil MTRDevice")); + MTR_LOG("%@ got subscription established", self); std::lock_guard lock(self->_lock); @@ -2602,34 +2811,50 @@ - (void)_setupSubscriptionWithReason:(NSString *)reason // Then async work that shouldn't be performed on the matter queue dispatch_async(self.queue, ^{ + mtr_strongify(self); + VerifyOrReturn(self, MTR_LOG_DEBUG("_setupSubscriptionWithReason subscription established async to device queue called back with nil MTRDevice")); + // OnSubscriptionEstablished [self _handleSubscriptionEstablished]; }); }, ^(void) { + mtr_strongify(self); + VerifyOrReturn(self, MTR_LOG_DEBUG("_setupSubscriptionWithReason subscription done called back with nil MTRDevice")); + MTR_LOG("%@ got subscription done", self); // Drop our pointer to the ReadClient immediately, since // it's about to be destroyed and we don't want to be // holding a dangling pointer. - std::lock_guard lock(self->_lock); - self->_currentReadClient = nullptr; - self->_currentSubscriptionCallback = nullptr; + [matterCPPObjectsHolder setReadClient:nullptr subscriptionCallback:nullptr]; // OnDone [self _doHandleSubscriptionReset:nil]; }, ^(void) { + mtr_strongify(self); + VerifyOrReturn(self, MTR_LOG_DEBUG("_setupSubscriptionWithReason subscription unsolicited message called back with nil MTRDevice")); + MTR_LOG("%@ got unsolicited message from publisher", self); // OnUnsolicitedMessageFromPublisher [self _handleUnsolicitedMessageFromPublisher]; }, ^(void) { + mtr_strongify(self); + VerifyOrReturn(self, MTR_LOG_DEBUG("_setupSubscriptionWithReason subscription report begin called back with nil MTRDevice")); + MTR_LOG("%@ got report begin", self); [self _handleReportBegin]; }, ^(void) { + mtr_strongify(self); + VerifyOrReturn(self, MTR_LOG_DEBUG("_setupSubscriptionWithReason subscription report end called back with nil MTRDevice")); + MTR_LOG("%@ got report end", self); dispatch_async(self.queue, ^{ + mtr_strongify(self); + VerifyOrReturn(self, MTR_LOG_DEBUG("_setupSubscriptionWithReason subscription report end async to device queue called back with nil MTRDevice")); + [self _handleReportEnd]; }); }); @@ -2716,10 +2941,7 @@ - (void)_setupSubscriptionWithReason:(NSString *)reason // Callback and ClusterStateCache and ReadClient will be deleted // when OnDone is called. - os_unfair_lock_lock(&self->_lock); - self->_currentReadClient = readClient.get(); - self->_currentSubscriptionCallback = callback.get(); - os_unfair_lock_unlock(&self->_lock); + [matterCPPObjectsHolder setReadClient:readClient.get() subscriptionCallback:callback.get()]; callback->AdoptReadClient(std::move(readClient)); callback->AdoptClusterStateCache(std::move(clusterStateCache)); callback.release(); @@ -2988,6 +3210,7 @@ static BOOL AttributeHasChangesOmittedQuality(MTRAttributePath * attributePath) MTRReadParams * readParams = (![readParamObject isEqual:[NSNull null]]) ? readParamObject : nil; MTRBaseDevice * baseDevice = [self newBaseDevice]; + mtr_weakify(self); [baseDevice readAttributePaths:attributePaths eventPaths:nil @@ -2995,6 +3218,8 @@ static BOOL AttributeHasChangesOmittedQuality(MTRAttributePath * attributePath) includeDataVersion:YES queue:self.queue completion:^(NSArray *> * _Nullable values, NSError * _Nullable error) { + mtr_strongify(self); + VerifyOrReturn(self, MTR_LOG_DEBUG("readAttributeWithEndpointID base device completion called back with nil MTRDevice")); if (values) { // Since the format is the same data-value dictionary, this looks like an // attribute report @@ -3129,6 +3354,7 @@ - (void)writeAttributeWithEndpointID:(NSNumber *)endpointID timedWriteTimeout = nil; } + mtr_weakify(self); [baseDevice _writeAttributeWithEndpointID:path.endpoint clusterID:path.cluster @@ -3137,6 +3363,8 @@ - (void)writeAttributeWithEndpointID:(NSNumber *)endpointID timedWriteTimeout:timedWriteTimeout queue:self.queue completion:^(NSArray *> * _Nullable values, NSError * _Nullable error) { + mtr_strongify(self); + VerifyOrReturn(self, MTR_LOG_DEBUG("writeAttributeWithEndpointID base device completion called back with nil MTRDevice")); if (error) { MTR_LOG_ERROR("Write attribute work item [%llu] failed: %@", workItemID, error); if (useValueAsExpectedValue) { @@ -3276,6 +3504,7 @@ - (void)_invokeCommandWithEndpointID:(NSNumber *)endpointID timedInvokeTimeout = @([cutoffTime timeIntervalSinceDate:now] * 1000); } MTRBaseDevice * baseDevice = [self newBaseDevice]; + mtr_weakify(self); [baseDevice _invokeCommandWithEndpointID:endpointID clusterID:clusterID @@ -3286,6 +3515,8 @@ - (void)_invokeCommandWithEndpointID:(NSNumber *)endpointID logCall:NO queue:self.queue completion:^(NSArray *> * _Nullable values, NSError * _Nullable error) { + mtr_strongify(self); + VerifyOrReturn(self, MTR_LOG_DEBUG("_invokeCommandWithEndpointID base device completion called back with nil MTRDevice")); // Log the data at the INFO level (not usually persisted permanently), // but make sure we log the work completion at the DEFAULT level. MTR_LOG("Invoke work item [%llu] received command response: %@ error: %@", workItemID, values, error); @@ -3687,10 +3918,15 @@ - (void)_pruneEndpointsIn:(MTRDeviceDataValueDictionary)previousPartsListValue [self _removeClusters:clusterPathsToRemove doRemoveFromDataStore:NO]; [self._concreteController.controllerDataStore clearStoredClusterDataForNodeID:self.nodeID endpointID:endpoint]; + mtr_weakify(self); [_deviceController asyncDispatchToMatterQueue:^{ - std::lock_guard lock(self->_lock); - if (self->_currentSubscriptionCallback) { - self->_currentSubscriptionCallback->ClearCachedAttributeState(static_cast(endpoint.unsignedLongLongValue)); + mtr_strongify(self); + VerifyOrReturn(self); + + @synchronized(self.matterCPPObjectsHolder) { + if (self.matterCPPObjectsHolder.subscriptionCallback) { + self.matterCPPObjectsHolder.subscriptionCallback->ClearCachedAttributeState(static_cast(endpoint.unsignedLongLongValue)); + } } } errorHandler:nil]; } @@ -3714,13 +3950,18 @@ - (void)_pruneClustersIn:(MTRDeviceDataValueDictionary)previousServerListValue } [self _removeClusters:clusterPathsToRemove doRemoveFromDataStore:YES]; + mtr_weakify(self); [_deviceController asyncDispatchToMatterQueue:^{ - std::lock_guard lock(self->_lock); - if (self->_currentSubscriptionCallback) { - for (NSNumber * cluster in toBeRemovedClusters) { - ConcreteClusterPath clusterPath(static_cast(endpointID.unsignedLongLongValue), - static_cast(cluster.unsignedLongLongValue)); - self->_currentSubscriptionCallback->ClearCachedAttributeState(clusterPath); + mtr_strongify(self); + VerifyOrReturn(self); + + @synchronized(self.matterCPPObjectsHolder) { + if (self.matterCPPObjectsHolder.subscriptionCallback) { + for (NSNumber * cluster in toBeRemovedClusters) { + ConcreteClusterPath clusterPath(static_cast(endpointID.unsignedLongLongValue), + static_cast(cluster.unsignedLongLongValue)); + self.matterCPPObjectsHolder.subscriptionCallback->ClearCachedAttributeState(clusterPath); + } } } } errorHandler:nil]; @@ -3738,14 +3979,19 @@ - (void)_pruneAttributesIn:(MTRDeviceDataValueDictionary)previousAttributeListVa [toBeRemovedAttributes minusSet:attributesStillInCluster]; [self _removeAttributes:toBeRemovedAttributes fromCluster:clusterPath]; + mtr_weakify(self); [_deviceController asyncDispatchToMatterQueue:^{ - std::lock_guard lock(self->_lock); - if (self->_currentSubscriptionCallback) { - for (NSNumber * attribute in toBeRemovedAttributes) { - ConcreteAttributePath attributePath(static_cast(clusterPath.endpoint.unsignedLongLongValue), - static_cast(clusterPath.cluster.unsignedLongLongValue), - static_cast(attribute.unsignedLongLongValue)); - self->_currentSubscriptionCallback->ClearCachedAttributeState(attributePath); + mtr_strongify(self); + VerifyOrReturn(self); + + @synchronized(self.matterCPPObjectsHolder) { + if (self.matterCPPObjectsHolder.subscriptionCallback) { + for (NSNumber * attribute in toBeRemovedAttributes) { + ConcreteAttributePath attributePath(static_cast(clusterPath.endpoint.unsignedLongLongValue), + static_cast(clusterPath.cluster.unsignedLongLongValue), + static_cast(attribute.unsignedLongLongValue)); + self.matterCPPObjectsHolder.subscriptionCallback->ClearCachedAttributeState(attributePath); + } } } } errorHandler:nil]; @@ -4457,7 +4703,11 @@ - (void)_deviceMayBeReachable { MTR_LOG("%@ _deviceMayBeReachable called, resetting subscription", self); // TODO: This should only be allowed for thread devices + mtr_weakify(self); [self._concreteController asyncGetCommissionerOnMatterQueue:^(Controller::DeviceCommissioner * commissioner) { + mtr_strongify(self); + VerifyOrReturn(self); + // Reset all of our subscription/session state and re-establish it all // from the start. Reset our subscription first, before tearing // down the session, so we don't have to worry about the diff --git a/src/darwin/Framework/CHIPTests/MTRPerControllerStorageTests.m b/src/darwin/Framework/CHIPTests/MTRPerControllerStorageTests.m index ca733c0b2f..d7c804b5d0 100644 --- a/src/darwin/Framework/CHIPTests/MTRPerControllerStorageTests.m +++ b/src/darwin/Framework/CHIPTests/MTRPerControllerStorageTests.m @@ -3610,4 +3610,85 @@ - (void)testMTRDeviceResetSubscription XCTAssertFalse([controller isRunning]); } +- (void)testMTRDeviceDealloc +{ + __auto_type * storageDelegate = [[MTRTestPerControllerStorageWithBulkReadWrite alloc] initWithControllerID:[NSUUID UUID]]; + + __auto_type * factory = [MTRDeviceControllerFactory sharedInstance]; + XCTAssertNotNil(factory); + + __auto_type queue = dispatch_queue_create("test.queue", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); + + __auto_type * rootKeys = [[MTRTestKeys alloc] init]; + XCTAssertNotNil(rootKeys); + + __auto_type * operationalKeys = [[MTRTestKeys alloc] init]; + XCTAssertNotNil(operationalKeys); + + NSNumber * nodeID = @(333); + NSNumber * fabricID = @(444); + + NSError * error; + + MTRPerControllerStorageTestsCertificateIssuer * certificateIssuer; + MTRDeviceController * controller = [self startControllerWithRootKeys:rootKeys + operationalKeys:operationalKeys + fabricID:fabricID + nodeID:nodeID + storage:storageDelegate + error:&error + certificateIssuer:&certificateIssuer]; + XCTAssertNil(error); + XCTAssertNotNil(controller); + XCTAssertTrue([controller isRunning]); + + XCTAssertEqualObjects(controller.controllerNodeID, nodeID); + + // Now commission the device, to test that that works. + NSNumber * deviceID = @(22); + certificateIssuer.nextNodeID = deviceID; + [self commissionWithController:controller newNodeID:deviceID]; + + // We should have established CASE using our operational key. + XCTAssertEqual(operationalKeys.signatureCount, 1); + + __block BOOL subscriptionReportEnd1 = NO; + XCTestExpectation * subscriptionCallbackDeleted = [self expectationWithDescription:@"Subscription callback deleted"]; + @autoreleasepool { + __auto_type * device = [MTRDevice deviceWithNodeID:deviceID controller:controller]; + __auto_type * delegate = [[MTRDeviceTestDelegate alloc] init]; + + XCTestExpectation * subscriptionReportBegin = [self expectationWithDescription:@"Subscription report begin"]; + + delegate.onReportBegin = ^{ + [subscriptionReportBegin fulfill]; + }; + + delegate.onReportEnd = ^{ + subscriptionReportEnd1 = YES; + }; + + delegate.onSubscriptionCallbackDelete = ^{ + [subscriptionCallbackDeleted fulfill]; + }; + + [device setDelegate:delegate queue:queue]; + + [self waitForExpectations:@[ subscriptionReportBegin ] timeout:60]; + } + + // report should still be ongoing + XCTAssertFalse(subscriptionReportEnd1); + + // dealloc -> delete should be called soon after the autoreleasepool reaps + [self waitForExpectations:@[ subscriptionCallbackDeleted ] timeout:60]; + + // Reset our commissionee. + __auto_type * baseDevice = [MTRBaseDevice deviceWithNodeID:deviceID controller:controller]; + ResetCommissionee(baseDevice, queue, self, kTimeoutInSeconds); + + [controller shutdown]; + XCTAssertFalse([controller isRunning]); +} + @end diff --git a/src/darwin/Framework/CHIPTests/TestHelpers/MTRDeviceTestDelegate.h b/src/darwin/Framework/CHIPTests/TestHelpers/MTRDeviceTestDelegate.h index 0ca5026a7c..4eb0ce7543 100644 --- a/src/darwin/Framework/CHIPTests/TestHelpers/MTRDeviceTestDelegate.h +++ b/src/darwin/Framework/CHIPTests/TestHelpers/MTRDeviceTestDelegate.h @@ -26,6 +26,7 @@ typedef void (^MTRDeviceTestDelegateDataHandler)(NSArray Date: Thu, 6 Feb 2025 20:13:02 +0000 Subject: [PATCH 11/39] Tc sc 4 1 bcm support (#36597) * [#36594] TC_SC_4_1, make BCM optional to meet test plan * [#36594] Remove new line * Restyled by prettier-yaml * Add ICDM.S.A0002 checking(#36597) * Restyled by prettier-yaml --------- Co-authored-by: Restyled.io --- .../suites/certification/Test_TC_SC_4_1.yaml | 77 +++++++++++++++---- 1 file changed, 64 insertions(+), 13 deletions(-) diff --git a/src/app/tests/suites/certification/Test_TC_SC_4_1.yaml b/src/app/tests/suites/certification/Test_TC_SC_4_1.yaml index fe353a9ffa..c786972719 100644 --- a/src/app/tests/suites/certification/Test_TC_SC_4_1.yaml +++ b/src/app/tests/suites/certification/Test_TC_SC_4_1.yaml @@ -44,28 +44,35 @@ config: defaultValue: 5000 tests: - - label: "Step 1: Wait for the commissioned device to be retrieved" + - label: + "Step 1: If (CADMIN.S.C01.Rsp) present, wait for the commissioned + device to be retrieved" cluster: "DelayCommands" command: "WaitForCommissionee" + PICS: CADMIN.S.C01.Rsp arguments: values: - name: "nodeId" value: nodeId - label: - "Step 1a: DUT is put in Commissioning Mode using Open Basic - Commissioning Window command " + "Step 1a: If (CADMIN.S.C01.Rsp) present, DUT is put in Commissioning + Mode using Open Basic Commissioning Window command " cluster: "Administrator Commissioning" command: "OpenBasicCommissioningWindow" + PICS: CADMIN.S.C01.Rsp timedInteractionTimeoutMs: 10000 arguments: values: - name: "CommissioningTimeout" value: 180 - - label: "Waiting after opening commissioning window" + - label: + "If (CADMIN.S.C01.Rsp) present, waiting after opening commissioning + window" cluster: "DelayCommands" command: "WaitForMs" + PICS: CADMIN.S.C01.Rsp arguments: values: - name: "ms" @@ -86,6 +93,16 @@ tests: isUpperCase: true isHexString: true + - label: + "Step 2aa: If (ICDM.S.A0002) TH reads from the DUT the + ActiveModeThreshold attribute" + PICS: ICDM.S.A0002 + cluster: "ICDManagement" + command: "readAttribute" + attribute: "ActiveModeThreshold" + response: + saveAs: ActiveModeThresholdValue + - label: "Step 2b: Service type must be _matterc._udp" verification: | Run the below commands within the mentioned time interval used in open-commissioning-window in step-1. @@ -112,6 +129,7 @@ tests: port = [5540] txt = ["PI=" "PH=36" "CM=1" "D=3840" "T=1" "VP=65521+32769"] + If "ICDM.S.A0002" check "SAT=ActiveModeThreshold Value" If we use Thread setup, then the Service Domain will be 422F10CDC290A406.local verify CM flag is 1 @@ -208,10 +226,11 @@ tests: value: deviceType - label: - "Step 2g: Check Commissioning Mode (_CM) subtype _CM must be present" + "Step 2g: If (CADMIN.S.C01.Rsp) present, check Commissioning Mode + (_CM) subtype _CM must be present" cluster: "DiscoveryCommands" command: "FindCommissionableByCommissioningMode" - + PICS: CADMIN.S.C01.Rsp - label: "Step 2h: key D must be present and represents the discriminator which must be encoded as a variable-length decimal value with up to 4 digits @@ -290,9 +309,12 @@ tests: constraints: maxValue: 65535 - - label: "Step 2n: TXT key for commissioning mode (CM) CM=1 must be present" + - label: + "Step 2n: If (CADMIN.S.C01.Rsp) present, TXT key for commissioning + mode (CM) CM=1 must be present" cluster: "DiscoveryCommands" command: "FindCommissionable" + PICS: CADMIN.S.C01.Rsp response: values: - name: "commissioningMode" @@ -400,9 +422,9 @@ tests: value: nodeId - label: - "Step 3a: DUT put in Commissioning Mode using Open Basic Commissioning - Window command, starting advertising Commissionable Node Discovery - service using DNS-SD" + "Step 3a: If (CADMIN.S.C01.Rsp) present, DUT put in Commissioning Mode + using Open Basic Commissioning Window command, starting advertising + Commissionable Node Discovery service using DNS-SD" PICS: CADMIN.S.C01.Rsp cluster: "Administrator Commissioning" command: "OpenBasicCommissioningWindow" @@ -412,9 +434,12 @@ tests: - name: "CommissioningTimeout" value: 180 - - label: "Waiting after opening commissioning window" + - label: + "If (CADMIN.S.C01.Rsp) present, waiting after opening commissioning + window" cluster: "DelayCommands" command: "WaitForMs" + PICS: CADMIN.S.C01.Rsp arguments: values: - name: "ms" @@ -436,6 +461,16 @@ tests: isHexString: true notValue: deviceInstanceNameBeforeReboot + - label: + "Step 4aa: If (ICDM.S.A0002) TH reads from the DUT the + ActiveModeThreshold attribute" + PICS: ICDM.S.A0002 + cluster: "ICDManagement" + command: "readAttribute" + attribute: "ActiveModeThreshold" + response: + saveAs: ActiveModeThresholdValue + - label: "Step 4b: service type must be _matterc._udp" verification: | Run the below avahi browse command in TH terminal @@ -457,6 +492,7 @@ tests: port = [5540] txt = ["PI=" "PH=36" "CM=1" "D=3840" "T=1" "VP=65521+32769"] + If "ICDM.S.A0002" check "SAT=ActiveModeThreshold Value" Service Domain 422F10CDC290A406.local verify CM flag is 1 @@ -553,9 +589,12 @@ tests: - name: "value" value: deviceType - - label: "Step 4h: Check Commissioning Mode (_CM) subtype _CM is present" + - label: + "Step 4h: If (CADMIN.S.C01.Rsp) present, check Commissioning Mode + (_CM) subtype _CM is present" cluster: "DiscoveryCommands" command: "FindCommissionableByCommissioningMode" + PICS: CADMIN.S.C01.Rsp - label: "Step 4i: key D must be present and represents the discriminator which @@ -636,9 +675,11 @@ tests: maxValue: 65535 - label: - "Step 4o: TXT key for commissioning mode (CM) key CM=1 must be present" + "Step 4o: If (CADMIN.S.C01.Rsp) present, TXT key for commissioning + mode (CM) key CM=1 must be present" cluster: "DiscoveryCommands" command: "FindCommissionable" + PICS: CADMIN.S.C01.Rsp response: values: - name: "commissioningMode" @@ -1095,6 +1136,16 @@ tests: isUpperCase: true isHexString: true + - label: + "Step 10aa: If ( && ICDM.S.A0002) TH reads from the DUT the + ActiveModeThreshold attribute" + PICS: ICDM.S.A0002 + cluster: "ICDManagement" + command: "readAttribute" + attribute: "ActiveModeThreshold" + response: + saveAs: ActiveModeThresholdValue + - label: "Step 10b: service type must be _matterc._udp" verification: | Run and Verify on the below output in TH terminal Log: (Below is the sample log , as RPI doesn't support the extended discovery) From a38f2aa1a11ed8515d4bfefd82ad13e7a019841f Mon Sep 17 00:00:00 2001 From: Adrian Gielniewski Date: Thu, 6 Feb 2025 21:40:09 +0100 Subject: [PATCH 12/39] Fix condition for building test vectors (#37423) Don't build test vectors if not building tests. Signed-off-by: Adrian Gielniewski --- src/credentials/BUILD.gn | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/credentials/BUILD.gn b/src/credentials/BUILD.gn index 63b86083a5..62975f17ee 100644 --- a/src/credentials/BUILD.gn +++ b/src/credentials/BUILD.gn @@ -108,10 +108,10 @@ static_library("credentials") { # is changed to generate it's own credentials instead of using Test credentials. # For some platforms test builds, which are bilding monolithic test library these files are not needed. import("${chip_root}/build/chip/tests.gni") - if (!(chip_build_tests && (chip_device_platform == "mbed" || - chip_device_platform == "openiotsdk" || - chip_device_platform == "nrfconnect" || - chip_device_platform == "esp32"))) { + if (chip_build_tests && !(chip_device_platform == "mbed" || + chip_device_platform == "openiotsdk" || + chip_device_platform == "nrfconnect" || + chip_device_platform == "esp32")) { sources += [ "tests/CHIPAttCert_test_vectors.cpp", "tests/CHIPAttCert_test_vectors.h", From 2a15d46ac7ed0ddd238d38924bb74d6a48c00062 Mon Sep 17 00:00:00 2001 From: Amine Alami <43780877+Alami-Amine@users.noreply.github.com> Date: Thu, 6 Feb 2025 22:36:18 +0100 Subject: [PATCH 13/39] [CASESession] Follow up to refactoring Sigma Parsing functions PR (#37425) * Make ConstructTBSData outparam a MutableByteSpan instead of a Pointer + Len * Adding a msgR2Decrypted struct member to improve clarity * Clarifying Logs when Assigining Peer SessionID * Removing TODO on validating signature before validation credentials * changing Logs to ScopedNodeID instead of just NodeID --- src/protocols/secure_channel/CASESession.cpp | 100 ++++++++++--------- src/protocols/secure_channel/CASESession.h | 17 ++-- 2 files changed, 61 insertions(+), 56 deletions(-) diff --git a/src/protocols/secure_channel/CASESession.cpp b/src/protocols/secure_channel/CASESession.cpp index c608c5b1ca..c314ce4048 100644 --- a/src/protocols/secure_channel/CASESession.cpp +++ b/src/protocols/secure_channel/CASESession.cpp @@ -1054,7 +1054,7 @@ CASESession::NextStep CASESession::HandleSigma1(System::PacketBufferHandle && ms ReturnErrorVariantOnFailure(NextStep, ParseSigma1(tlvReader, parsedSigma1)); - ChipLogDetail(SecureChannel, "Peer assigned session key ID %d", parsedSigma1.initiatorSessionId); + ChipLogDetail(SecureChannel, "Peer (Initiator) assigned session ID %d", parsedSigma1.initiatorSessionId); SetPeerSessionId(parsedSigma1.initiatorSessionId); // Set the Session parameters provided in the Sigma1 message @@ -1222,23 +1222,23 @@ CHIP_ERROR CASESession::PrepareSigma2(EncodeSigma2Inputs & outSigma2Data) ReturnErrorOnFailure(DeriveSigmaKey(saltSpan, ByteSpan(kKDFSR2Info), sr2k)); // Construct Sigma2 TBS Data - size_t msgR2SignedLen = EstimateStructOverhead(kMaxCHIPCertLength, // responderNoc - kMaxCHIPCertLength, // responderICAC - kP256_PublicKey_Length, // responderEphPubKey - kP256_PublicKey_Length // InitiatorEphPubKey - ); - P256ECDSASignature tbsData2Signature; { + size_t msgR2SignedLen = EstimateStructOverhead(kMaxCHIPCertLength, // responderNoc + kMaxCHIPCertLength, // responderICAC + kP256_PublicKey_Length, // responderEphPubKey + kP256_PublicKey_Length // InitiatorEphPubKey + ); + chip::Platform::ScopedMemoryBuffer msgR2Signed; VerifyOrReturnError(msgR2Signed.Alloc(msgR2SignedLen), CHIP_ERROR_NO_MEMORY); + MutableByteSpan msgR2SignedSpan{ msgR2Signed.Get(), msgR2SignedLen }; ReturnErrorOnFailure(ConstructTBSData(nocCert, icaCert, ByteSpan(mEphemeralKey->Pubkey(), mEphemeralKey->Pubkey().Length()), - ByteSpan(mRemotePubKey, mRemotePubKey.Length()), msgR2Signed.Get(), msgR2SignedLen)); + ByteSpan(mRemotePubKey, mRemotePubKey.Length()), msgR2SignedSpan)); // Generate a Signature - ReturnErrorOnFailure( - mFabricsTable->SignWithOpKeypair(mFabricIndex, ByteSpan{ msgR2Signed.Get(), msgR2SignedLen }, tbsData2Signature)); + ReturnErrorOnFailure(mFabricsTable->SignWithOpKeypair(mFabricIndex, msgR2SignedSpan, tbsData2Signature)); } // Construct Sigma2 TBE Data size_t msgR2SignedEncLen = EstimateStructOverhead(nocCert.size(), // responderNoc @@ -1381,7 +1381,8 @@ CHIP_ERROR CASESession::HandleSigma2Resume(System::PacketBufferHandle && msg) GetRemoteSessionParameters()); } - ChipLogDetail(SecureChannel, "Peer assigned session ID %d", parsedSigma2Resume.responderSessionId); + ChipLogDetail(SecureChannel, "Peer " ChipLogFormatScopedNodeId " assigned session ID %d", ChipLogValueScopedNodeId(GetPeer()), + parsedSigma2Resume.responderSessionId); SetPeerSessionId(parsedSigma2Resume.responderSessionId); if (mSessionResumptionStorage != nullptr) @@ -1517,12 +1518,15 @@ CHIP_ERROR CASESession::HandleSigma2(System::PacketBufferHandle && msg) nullptr, 0, parsedSigma2.msgR2MIC.data(), parsedSigma2.msgR2MIC.size(), sr2k.KeyHandle(), kTBEData2_Nonce, kTBEDataNonceLength, parsedSigma2.msgR2EncryptedPayload.data())); + parsedSigma2.msgR2Decrypted = std::move(parsedSigma2.msgR2Encrypted); + size_t msgR2DecryptedLength = parsedSigma2.msgR2EncryptedPayload.size(); + ContiguousBufferTLVReader decryptedDataTlvReader; - decryptedDataTlvReader.Init(parsedSigma2.msgR2EncryptedPayload.data(), parsedSigma2.msgR2EncryptedPayload.size()); + decryptedDataTlvReader.Init(parsedSigma2.msgR2Decrypted.Get(), msgR2DecryptedLength); ParsedSigma2TBEData parsedSigma2TBEData; ReturnErrorOnFailure(ParseSigma2TBEData(decryptedDataTlvReader, parsedSigma2TBEData)); - // Validate responder identity located in msgR2Encrypted + // Validate responder identity located in msgR2Decrypted // Constructing responder identity P256PublicKey responderPublicKey; { @@ -1540,7 +1544,7 @@ CHIP_ERROR CASESession::HandleSigma2(System::PacketBufferHandle && msg) VerifyOrReturnError(mPeerNodeId == responderNodeId, CHIP_ERROR_INVALID_CASE_PARAMETER); } - // Construct msgR2Signed and validate the signature in msgR2Encrypted. + // Construct msgR2Signed and validate the signature in msgR2Decrypted. size_t msgR2SignedLen = EstimateStructOverhead(parsedSigma2TBEData.responderNOC.size(), // resonderNOC parsedSigma2TBEData.responderICAC.size(), // responderICAC kP256_PublicKey_Length, // responderEphPubKey @@ -1549,16 +1553,18 @@ CHIP_ERROR CASESession::HandleSigma2(System::PacketBufferHandle && msg) chip::Platform::ScopedMemoryBuffer msgR2Signed; VerifyOrReturnError(msgR2Signed.Alloc(msgR2SignedLen), CHIP_ERROR_NO_MEMORY); + MutableByteSpan msgR2SignedSpan{ msgR2Signed.Get(), msgR2SignedLen }; - ReturnErrorOnFailure(ConstructTBSData( - parsedSigma2TBEData.responderNOC, parsedSigma2TBEData.responderICAC, ByteSpan(mRemotePubKey, mRemotePubKey.Length()), - ByteSpan(mEphemeralKey->Pubkey(), mEphemeralKey->Pubkey().Length()), msgR2Signed.Get(), msgR2SignedLen)); + ReturnErrorOnFailure(ConstructTBSData(parsedSigma2TBEData.responderNOC, parsedSigma2TBEData.responderICAC, + ByteSpan(mRemotePubKey, mRemotePubKey.Length()), + ByteSpan(mEphemeralKey->Pubkey(), mEphemeralKey->Pubkey().Length()), msgR2SignedSpan)); // Validate signature - ReturnErrorOnFailure( - responderPublicKey.ECDSA_validate_msg_signature(msgR2Signed.Get(), msgR2SignedLen, parsedSigma2TBEData.tbsData2Signature)); + ReturnErrorOnFailure(responderPublicKey.ECDSA_validate_msg_signature(msgR2SignedSpan.data(), msgR2SignedSpan.size(), + parsedSigma2TBEData.tbsData2Signature)); - ChipLogDetail(SecureChannel, "Peer assigned session ID %d", parsedSigma2.responderSessionId); + ChipLogDetail(SecureChannel, "Peer " ChipLogFormatScopedNodeId " assigned session ID %d", ChipLogValueScopedNodeId(GetPeer()), + parsedSigma2.responderSessionId); SetPeerSessionId(parsedSigma2.responderSessionId); std::copy(parsedSigma2TBEData.resumptionId.begin(), parsedSigma2TBEData.resumptionId.end(), mNewResumptionId.begin()); @@ -1728,14 +1734,18 @@ CHIP_ERROR CASESession::SendSigma3a() ReturnErrorOnFailure(mFabricsTable->FetchNOCCert(mFabricIndex, data.nocCert)); // Prepare Sigma3 TBS Data Blob - data.msg_r3_signed_len = - EstimateStructOverhead(data.icaCert.size(), data.nocCert.size(), kP256_PublicKey_Length, kP256_PublicKey_Length); + size_t msgR3SignedLen = EstimateStructOverhead(data.nocCert.size(), // initiatorNOC + data.icaCert.size(), // initiatorICAC + kP256_PublicKey_Length, // initiatorEphPubKey + kP256_PublicKey_Length // responderEphPubKey + ); - VerifyOrReturnError(data.msg_R3_Signed.Alloc(data.msg_r3_signed_len), CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(data.msgR3Signed.Alloc(msgR3SignedLen), CHIP_ERROR_NO_MEMORY); + data.msgR3SignedSpan = MutableByteSpan{ data.msgR3Signed.Get(), msgR3SignedLen }; - ReturnErrorOnFailure( - ConstructTBSData(data.nocCert, data.icaCert, ByteSpan(mEphemeralKey->Pubkey(), mEphemeralKey->Pubkey().Length()), - ByteSpan(mRemotePubKey, mRemotePubKey.Length()), data.msg_R3_Signed.Get(), data.msg_r3_signed_len)); + ReturnErrorOnFailure(ConstructTBSData(data.nocCert, data.icaCert, + ByteSpan(mEphemeralKey->Pubkey(), mEphemeralKey->Pubkey().Length()), + ByteSpan(mRemotePubKey, mRemotePubKey.Length()), data.msgR3SignedSpan)); if (data.keystore != nullptr) { @@ -1759,14 +1769,12 @@ CHIP_ERROR CASESession::SendSigma3b(SendSigma3Data & data, bool & cancel) if (data.keystore != nullptr) { // Recommended case: delegate to operational keystore - ReturnErrorOnFailure(data.keystore->SignWithOpKeypair( - data.fabricIndex, ByteSpan{ data.msg_R3_Signed.Get(), data.msg_r3_signed_len }, data.tbsData3Signature)); + ReturnErrorOnFailure(data.keystore->SignWithOpKeypair(data.fabricIndex, data.msgR3SignedSpan, data.tbsData3Signature)); } else { // Legacy case: delegate to fabric table fabric info - ReturnErrorOnFailure(data.fabricTable->SignWithOpKeypair( - data.fabricIndex, ByteSpan{ data.msg_R3_Signed.Get(), data.msg_r3_signed_len }, data.tbsData3Signature)); + ReturnErrorOnFailure(data.fabricTable->SignWithOpKeypair(data.fabricIndex, data.msgR3SignedSpan, data.tbsData3Signature)); } // Prepare Sigma3 TBE Data Blob @@ -1950,17 +1958,18 @@ CHIP_ERROR CASESession::HandleSigma3a(System::PacketBufferHandle && msg) SuccessOrExit(err = ParseSigma3TBEData(decryptedDataTlvReader, data)); // Step 3 - Construct Sigma3 TBS Data - data.msgR3SignedLen = TLV::EstimateStructOverhead(data.initiatorNOC.size(), // initiatorNOC - data.initiatorICAC.size(), // initiatorICAC - kP256_PublicKey_Length, // initiatorEphPubKey - kP256_PublicKey_Length // responderEphPubKey + size_t msgR3SignedLen = TLV::EstimateStructOverhead(data.initiatorNOC.size(), // initiatorNOC + data.initiatorICAC.size(), // initiatorICAC + kP256_PublicKey_Length, // initiatorEphPubKey + kP256_PublicKey_Length // responderEphPubKey ); - VerifyOrExit(data.msgR3Signed.Alloc(data.msgR3SignedLen), err = CHIP_ERROR_NO_MEMORY); + VerifyOrExit(data.msgR3Signed.Alloc(msgR3SignedLen), err = CHIP_ERROR_NO_MEMORY); + data.msgR3SignedSpan = MutableByteSpan{ data.msgR3Signed.Get(), msgR3SignedLen }; SuccessOrExit(err = ConstructTBSData(data.initiatorNOC, data.initiatorICAC, ByteSpan(mRemotePubKey, mRemotePubKey.Length()), ByteSpan(mEphemeralKey->Pubkey(), mEphemeralKey->Pubkey().Length()), - data.msgR3Signed.Get(), data.msgR3SignedLen)); + data.msgR3SignedSpan)); // Prepare for Step 4/5 { @@ -1977,9 +1986,9 @@ CHIP_ERROR CASESession::HandleSigma3a(System::PacketBufferHandle && msg) // initiatorNOC and initiatorICAC are spans into msgR3Encrypted // which is going away, so to save memory, redirect them to their - // copies in msg_R3_signed, which is staying around + // copies in msgR3Signed, which is staying around TLV::ContiguousBufferTLVReader signedDataTlvReader; - signedDataTlvReader.Init(data.msgR3Signed.Get(), data.msgR3SignedLen); + signedDataTlvReader.Init(data.msgR3SignedSpan); SuccessOrExit(err = signedDataTlvReader.Next(containerType, AnonymousTag())); SuccessOrExit(err = signedDataTlvReader.EnterContainer(containerType)); @@ -2089,14 +2098,9 @@ CHIP_ERROR CASESession::HandleSigma3b(HandleSigma3Data & data, bool & cancel) unused, initiatorFabricId, data.initiatorNodeId, initiatorPublicKey)); VerifyOrReturnError(data.fabricId == initiatorFabricId, CHIP_ERROR_INVALID_CASE_PARAMETER); - // TODO - Validate message signature prior to validating the received operational credentials. - // The op cert check requires traversal of cert chain, that is a more expensive operation. - // If message signature check fails, the cert chain check will be unnecessary, but with the - // current flow of code, a malicious node can trigger a DoS style attack on the device. - // The same change should be made in Sigma2 processing. // Step 7 - Validate Signature - ReturnErrorOnFailure( - initiatorPublicKey.ECDSA_validate_msg_signature(data.msgR3Signed.Get(), data.msgR3SignedLen, data.tbsData3Signature)); + ReturnErrorOnFailure(initiatorPublicKey.ECDSA_validate_msg_signature(data.msgR3SignedSpan.data(), data.msgR3SignedSpan.size(), + data.tbsData3Signature)); return CHIP_NO_ERROR; } @@ -2241,12 +2245,12 @@ CHIP_ERROR CASESession::ValidateSigmaResumeMIC(const ByteSpan & resumeMIC, const } CHIP_ERROR CASESession::ConstructTBSData(const ByteSpan & senderNOC, const ByteSpan & senderICAC, const ByteSpan & senderPubKey, - const ByteSpan & receiverPubKey, uint8_t * tbsData, size_t & tbsDataLen) + const ByteSpan & receiverPubKey, MutableByteSpan & outTbsData) { TLVWriter tlvWriter; TLVType outerContainerType = kTLVType_NotSpecified; - tlvWriter.Init(tbsData, tbsDataLen); + tlvWriter.Init(outTbsData); ReturnErrorOnFailure(tlvWriter.StartContainer(AnonymousTag(), kTLVType_Structure, outerContainerType)); ReturnErrorOnFailure(tlvWriter.Put(AsTlvContextTag(TBSDataTags::kSenderNOC), senderNOC)); if (!senderICAC.empty()) @@ -2257,7 +2261,7 @@ CHIP_ERROR CASESession::ConstructTBSData(const ByteSpan & senderNOC, const ByteS ReturnErrorOnFailure(tlvWriter.Put(AsTlvContextTag(TBSDataTags::kReceiverPubKey), receiverPubKey)); ReturnErrorOnFailure(tlvWriter.EndContainer(outerContainerType)); ReturnErrorOnFailure(tlvWriter.Finalize()); - tbsDataLen = static_cast(tlvWriter.GetLengthWritten()); + outTbsData.reduce_size(static_cast(tlvWriter.GetLengthWritten())); return CHIP_NO_ERROR; } diff --git a/src/protocols/secure_channel/CASESession.h b/src/protocols/secure_channel/CASESession.h index d232e42d22..ccbcc6dd1c 100644 --- a/src/protocols/secure_channel/CASESession.h +++ b/src/protocols/secure_channel/CASESession.h @@ -249,6 +249,7 @@ class DLL_EXPORT CASESession : public Messaging::UnsolicitedMessageHandler, ByteSpan responderEphPubKey; Platform::ScopedMemoryBufferWithSize msgR2Encrypted; + Platform::ScopedMemoryBufferWithSize msgR2Decrypted; // Below ByteSpans are Backed by: msgR2Encrypted buffer // Lifetime: Valid as long as msgR2Encrypted is not released MutableByteSpan msgR2EncryptedPayload; @@ -260,8 +261,8 @@ class DLL_EXPORT CASESession : public Messaging::UnsolicitedMessageHandler, struct ParsedSigma2TBEData { - // Below ByteSpans are Backed by: msgR2Encrypted Buffer, member of ParsedSigma2 struct - // Lifetime: Valid for the lifetime of the instance of ParsedSigma2 that contains the msgR2Encrypted Buffer. + // Below ByteSpans are Backed by: msgR2Decrypted Buffer, member of ParsedSigma2 struct + // Lifetime: Valid for the lifetime of the instance of ParsedSigma2 that contains the msgR2Decrypted Buffer. ByteSpan responderNOC; ByteSpan responderICAC; ByteSpan resumptionId; @@ -297,8 +298,8 @@ class DLL_EXPORT CASESession : public Messaging::UnsolicitedMessageHandler, const FabricTable * fabricTable; const Crypto::OperationalKeystore * keystore; - chip::Platform::ScopedMemoryBuffer msg_R3_Signed; - size_t msg_r3_signed_len; + chip::Platform::ScopedMemoryBuffer msgR3Signed; + MutableByteSpan msgR3SignedSpan; chip::Platform::ScopedMemoryBuffer msg_R3_Encrypted; size_t msg_r3_encrypted_len; @@ -315,7 +316,7 @@ class DLL_EXPORT CASESession : public Messaging::UnsolicitedMessageHandler, struct HandleSigma3Data { chip::Platform::ScopedMemoryBuffer msgR3Signed; - size_t msgR3SignedLen; + MutableByteSpan msgR3SignedSpan; // Below ByteSpans are Backed by: msgR3Encrypted Buffer, local to the HandleSigma3a() method, // The Spans are later modified to point to the msgR3Signed member of this struct. @@ -382,9 +383,9 @@ class DLL_EXPORT CASESession : public Messaging::UnsolicitedMessageHandler, * Parse a decrypted TBEData2Encrypted message. This function will return success only if the message passes schema checks. * * @param tlvReader a reference to the TLVReader that points to the decrypted TBEData2Encrypted buffer (i.e. - * msgR2Encrypted member of ParsedSigma2 struct) + * msgR2Decrypted member of ParsedSigma2 struct) * @param outParsedSigma2TBEData a reference to ParsedSigma2TBEData. All members of parsedMessage will stay valid as long - * as the msgR2Encrypted member of ParsedSigma2 is valid + * as the msgR2Decrypted member of ParsedSigma2 is valid * * @note Calls to this function must always be made with a newly created and fresh ParsedSigma2TBEData parameter. **/ @@ -513,7 +514,7 @@ class DLL_EXPORT CASESession : public Messaging::UnsolicitedMessageHandler, CHIP_ERROR ConstructSaltSigma2(const ByteSpan & rand, const Crypto::P256PublicKey & pubkey, const ByteSpan & ipk, MutableByteSpan & salt); CHIP_ERROR ConstructTBSData(const ByteSpan & senderNOC, const ByteSpan & senderICAC, const ByteSpan & senderPubKey, - const ByteSpan & receiverPubKey, uint8_t * tbsData, size_t & tbsDataLen); + const ByteSpan & receiverPubKey, MutableByteSpan & outTbsData); CHIP_ERROR ConstructSaltSigma3(const ByteSpan & ipk, MutableByteSpan & salt); CHIP_ERROR ConstructSigmaResumeKey(const ByteSpan & initiatorRandom, const ByteSpan & resumptionID, const ByteSpan & skInfo, From 93114c759975ef06440ae3377f2d65443bb76e6d Mon Sep 17 00:00:00 2001 From: C Freeman Date: Thu, 6 Feb 2025 17:25:35 -0500 Subject: [PATCH 14/39] Auto-select data model set based on specification version (#37394) * Auto-select data model set based on specification version * Remove extra includes * Fix PICS test test to add SoftwareVersion with pics * Restyled by isort * linter * Omit TestSpecParsingSelection test from app testing --------- Co-authored-by: Restyled.io --- .github/workflows/tests.yaml | 1 + src/python_testing/TC_AccessChecker.py | 5 +- src/python_testing/TC_DeviceConformance.py | 6 +- src/python_testing/TC_pics_checker.py | 11 +- src/python_testing/TestConformanceTest.py | 8 +- .../TestSpecParsingDeviceType.py | 5 +- .../TestSpecParsingSelection.py | 149 ++++++++++++++++++ src/python_testing/TestSpecParsingSupport.py | 3 +- .../chip/testing/basic_composition.py | 22 +++ .../chip/testing/matter_testing.py | 7 +- .../chip/testing/runner.py | 1 + .../chip/testing/spec_parsing.py | 27 +++- src/python_testing/test_metadata.yaml | 2 + .../example_pics_xml_basic_info.xml | 21 +++ .../test_testing/test_IDM_10_4.py | 1 + 15 files changed, 247 insertions(+), 22 deletions(-) create mode 100644 src/python_testing/TestSpecParsingSelection.py diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 1ac9f82f88..9024b0e3a2 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -537,6 +537,7 @@ jobs: scripts/run_in_python_env.sh out/venv 'python3 src/python_testing/TestIdChecks.py' scripts/run_in_python_env.sh out/venv 'python3 src/python_testing/TestMatterTestingSupport.py' scripts/run_in_python_env.sh out/venv 'python3 src/python_testing/TestSpecParsingDeviceType.py' + scripts/run_in_python_env.sh out/venv 'python3 src/python_testing/TestSpecParsingSelection.py' scripts/run_in_python_env.sh out/venv 'python3 src/python_testing/TestSpecParsingSupport.py' - name: Run Tests diff --git a/src/python_testing/TC_AccessChecker.py b/src/python_testing/TC_AccessChecker.py index 5f3b3d69ec..03595d7ac1 100644 --- a/src/python_testing/TC_AccessChecker.py +++ b/src/python_testing/TC_AccessChecker.py @@ -28,7 +28,7 @@ from chip.testing.global_attribute_ids import GlobalAttributeIds from chip.testing.matter_testing import (AttributePathLocation, ClusterPathLocation, MatterBaseTest, TestStep, async_test_body, default_matter_test_main) -from chip.testing.spec_parsing import XmlCluster, build_xml_clusters +from chip.testing.spec_parsing import XmlCluster from chip.tlv import uint @@ -72,7 +72,8 @@ async def setup_class(self): self.user_params["use_pase_only"] = False super().setup_class() await self.setup_class_helper() - self.xml_clusters, self.problems = build_xml_clusters() + self.build_spec_xmls() + acl_attr = Clusters.AccessControl.Attributes.Acl self.default_acl = await self.read_single_attribute_check_success(cluster=Clusters.AccessControl, attribute=acl_attr) self._record_errors() diff --git a/src/python_testing/TC_DeviceConformance.py b/src/python_testing/TC_DeviceConformance.py index de6714abb3..d2d22ecee7 100644 --- a/src/python_testing/TC_DeviceConformance.py +++ b/src/python_testing/TC_DeviceConformance.py @@ -47,16 +47,14 @@ device_type_id_type, is_valid_device_type_id) from chip.testing.matter_testing import (AttributePathLocation, ClusterPathLocation, CommandPathLocation, DeviceTypePathLocation, MatterBaseTest, ProblemNotice, ProblemSeverity, async_test_body, default_matter_test_main) -from chip.testing.spec_parsing import CommandType, build_xml_clusters, build_xml_device_types +from chip.testing.spec_parsing import CommandType from chip.tlv import uint class DeviceConformanceTests(BasicCompositionTests): async def setup_class_helper(self): await super().setup_class_helper() - self.xml_clusters, self.problems = build_xml_clusters() - self.xml_device_types, problems = build_xml_device_types() - self.problems.extend(problems) + self.build_spec_xmls() def _get_device_type_id(self, device_type_name: str) -> int: id = [id for id, dt in self.xml_device_types.items() if dt.name.lower() == device_type_name.lower()] diff --git a/src/python_testing/TC_pics_checker.py b/src/python_testing/TC_pics_checker.py index 07e8613cc1..510429dff0 100644 --- a/src/python_testing/TC_pics_checker.py +++ b/src/python_testing/TC_pics_checker.py @@ -20,9 +20,9 @@ from chip.testing.basic_composition import BasicCompositionTests from chip.testing.global_attribute_ids import GlobalAttributeIds from chip.testing.matter_testing import (AttributePathLocation, ClusterPathLocation, CommandPathLocation, FeaturePathLocation, - MatterBaseTest, ProblemLocation, TestStep, async_test_body, default_matter_test_main) + MatterBaseTest, TestStep, UnknownProblemLocation, async_test_body, + default_matter_test_main) from chip.testing.pics import accepted_cmd_pics_str, attribute_pics_str, feature_pics_str, generated_cmd_pics_str -from chip.testing.spec_parsing import build_xml_clusters from mobly import asserts @@ -31,10 +31,7 @@ class TC_PICS_Checker(MatterBaseTest, BasicCompositionTests): async def setup_class(self): super().setup_class() await self.setup_class_helper(False) - # build_xml_cluster returns a list of issues found when paring the XML - # Problems in the XML shouldn't cause test failure, but we want them recorded - # so they are added to the list of problems that get output when the test set completes. - self.xml_clusters, self.problems = build_xml_clusters() + self.build_spec_xmls() def _check_and_record_errors(self, location, required, pics): if required and not self.check_pics(pics): @@ -178,7 +175,7 @@ def test_TC_IDM_10_4(self): self.step(7) if self.is_pics_sdk_ci_only: - self.record_error("PICS check", location=ProblemLocation(), + self.record_error("PICS check", location=UnknownProblemLocation(), problem="PICS PICS_SDK_CI_ONLY found in PICS list. This PICS is disallowed for certification.") self.success = False diff --git a/src/python_testing/TestConformanceTest.py b/src/python_testing/TestConformanceTest.py index c7b73495b6..4c446ad73b 100644 --- a/src/python_testing/TestConformanceTest.py +++ b/src/python_testing/TestConformanceTest.py @@ -22,7 +22,7 @@ from chip.testing.conformance import ConformanceDecision from chip.testing.global_attribute_ids import GlobalAttributeIds from chip.testing.matter_testing import MatterBaseTest, async_test_body, default_matter_test_main -from chip.testing.spec_parsing import build_xml_clusters, build_xml_device_types +from chip.testing.spec_parsing import PrebuiltDataModelDirectory, build_xml_clusters, build_xml_device_types from mobly import asserts from TC_DeviceConformance import DeviceConformanceTests @@ -118,8 +118,10 @@ def is_mandatory(conformance): class TestConformanceSupport(MatterBaseTest, DeviceConformanceTests): def setup_class(self): - self.xml_clusters, self.problems = build_xml_clusters() - self.xml_device_types, problems = build_xml_device_types() + # Latest fully qualified version + # TODO: It might be good to find a way to run this against each directory. + self.xml_clusters, self.problems = build_xml_clusters(PrebuiltDataModelDirectory.k1_4) + self.xml_device_types, problems = build_xml_device_types(PrebuiltDataModelDirectory.k1_4) self.problems.extend(problems) @async_test_body diff --git a/src/python_testing/TestSpecParsingDeviceType.py b/src/python_testing/TestSpecParsingDeviceType.py index 66a41b0fc5..baf7ac4d9c 100644 --- a/src/python_testing/TestSpecParsingDeviceType.py +++ b/src/python_testing/TestSpecParsingDeviceType.py @@ -35,8 +35,9 @@ def test_spec_device_parsing(self): print(str(d)) def setup_class(self): - self.xml_clusters, self.xml_cluster_problems = build_xml_clusters() - self.xml_device_types, self.xml_device_types_problems = build_xml_device_types() + # Latest fully qualified release + self.xml_clusters, self.xml_cluster_problems = build_xml_clusters(PrebuiltDataModelDirectory.k1_4) + self.xml_device_types, self.xml_device_types_problems = build_xml_device_types(PrebuiltDataModelDirectory.k1_4) self.device_type_id = 0xBBEF self.revision = 2 diff --git a/src/python_testing/TestSpecParsingSelection.py b/src/python_testing/TestSpecParsingSelection.py new file mode 100644 index 0000000000..51e76a8f59 --- /dev/null +++ b/src/python_testing/TestSpecParsingSelection.py @@ -0,0 +1,149 @@ +# +# Copyright (c) 2025 Project CHIP Authors +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import chip.clusters as Clusters +from chip.testing.conformance import ConformanceDecision, ConformanceException +from chip.testing.global_attribute_ids import is_standard_attribute_id +from chip.testing.matter_testing import MatterBaseTest, default_matter_test_main +from chip.testing.spec_parsing import PrebuiltDataModelDirectory, build_xml_clusters, dm_from_spec_version +from chip.tlv import uint +from mobly import asserts, signals +from TC_DeviceConformance import DeviceConformanceTests + + +class TestSpecParsingSelection(MatterBaseTest, DeviceConformanceTests): + def setup_class(self): + # Overriding the DeviceConformanceTest setup_class so we don't go out to a real device + pass + + def test_dm_from_spec_version(self): + asserts.assert_equal(dm_from_spec_version(0x01030000), PrebuiltDataModelDirectory.k1_3, + "Incorrect directory selected for 1.3 with patch 0") + asserts.assert_equal(dm_from_spec_version(0x01030100), PrebuiltDataModelDirectory.k1_3, + "Incorrect directory selected for 1.3 with patch 1") + asserts.assert_equal(dm_from_spec_version(0x01040100), PrebuiltDataModelDirectory.k1_4_1, + "Incorrect directory selected for 1.4.1") + asserts.assert_equal(dm_from_spec_version(0x01040100), PrebuiltDataModelDirectory.k1_4_1, + "Incorrect directory selected for 1.4.1") + asserts.assert_equal(dm_from_spec_version(0x01050000), PrebuiltDataModelDirectory.kMaster, + "Incorrect directory selected for 1.5") + + # We don't have data model files for 1.2, so these should error + with asserts.assert_raises(ConformanceException, "Expected assertion was not raised for spec version 1.2"): + dm_from_spec_version(0x01020000) + + # Any dot release besides 0 and 1 for 1.4 should error + with asserts.assert_raises(ConformanceException, "Data model incorrectly identified for 1.4.2"): + dm_from_spec_version(0x01040200) + + with asserts.assert_raises(ConformanceException, "Data model incorrectly identified for 1.4.FF"): + dm_from_spec_version(0x0104FF00) + + # Any dot release besides 0 for 1.5 should error + with asserts.assert_raises(ConformanceException, "Data model incorrectly identified for 1.5.1"): + dm_from_spec_version(0x01050100) + with asserts.assert_raises(ConformanceException, "Data model incorrectly identified for 1.5.FF"): + dm_from_spec_version(0x0105FF00) + + # Any value with stuff in reserved should error + with asserts.assert_raises(ConformanceException, "Error not returned for specification revision with non-zero reserved values"): + dm_from_spec_version(0x01030001) + with asserts.assert_raises(ConformanceException, "Error not returned for specification revision with non-zero reserved values"): + dm_from_spec_version(0x01040001) + with asserts.assert_raises(ConformanceException, "Error not returned for specification revision with non-zero reserved values"): + dm_from_spec_version(0x01040101) + with asserts.assert_raises(ConformanceException, "Error not returned for specification revision with non-zero reserved values"): + dm_from_spec_version(0x01050001) + + def _create_device(self, spec_version: uint, tc_enabled: bool): + # Build at 1.4.1 so we can have TC info + xml_clusters, _ = build_xml_clusters(PrebuiltDataModelDirectory.k1_4_1) + + gc_feature_map = Clusters.GeneralCommissioning.Bitmaps.Feature.kTermsAndConditions if tc_enabled else 0 + + def create_cluster_globals(cluster, feature_map): + spec_attributes = xml_clusters[cluster.id].attributes + spec_accepted_commands = xml_clusters[cluster.id].accepted_commands + spec_generated_commands = xml_clusters[cluster.id].generated_commands + # Build just the lists - basic composition checks the wildcard against the lists, conformance just uses lists + attributes = [id for id, a in spec_attributes.items() if a.conformance( + feature_map, [], []).decision == ConformanceDecision.MANDATORY] + accepted_commands = [id for id, c in spec_accepted_commands.items() if c.conformance( + feature_map, [], []).decision == ConformanceDecision.MANDATORY] + generated_commands = [id for id, c in spec_generated_commands.items() if c.conformance( + feature_map, [], []).decision == ConformanceDecision.MANDATORY] + attr = cluster.Attributes + + resp = {} + non_global_attrs = [a for a in attributes if is_standard_attribute_id(a)] + for attribute_id in non_global_attrs: + # We don't use the values in these tests, set them all to 0. The types are wrong, but it shouldn't matter + resp[Clusters.ClusterObjects.ALL_ATTRIBUTES[cluster.id][attribute_id]] = 0 + + resp[attr.AttributeList] = attributes + resp[attr.AcceptedCommandList] = accepted_commands + resp[attr.GeneratedCommandList] = generated_commands + resp[attr.FeatureMap] = feature_map + resp[attr.ClusterRevision] = xml_clusters[cluster.id].revision + + return resp + + def get_tlv(resp): + # This only works because there are no structs in here. + # structs need special handling. Beware. + return {k.attribute_id: v for k, v in resp.items()} + + gc_resp = create_cluster_globals(Clusters.GeneralCommissioning, gc_feature_map) + bi_resp = create_cluster_globals(Clusters.BasicInformation, 0) + bi_resp[Clusters.BasicInformation.Attributes.SpecificationVersion] = spec_version + + self.endpoints = {0: {Clusters.GeneralCommissioning: gc_resp, Clusters.BasicInformation: bi_resp}} + self.endpoints_tlv = {0: {Clusters.GeneralCommissioning.id: get_tlv( + gc_resp), Clusters.BasicInformation.id: get_tlv(bi_resp)}} + + def _run_conformance_against_device(self, spec_version: uint, tc_enabled: bool, expect_success_conformance: bool, expect_success_revisions: bool): + self._create_device(spec_version, tc_enabled) + # build the spec XMLs for the stated version + self.build_spec_xmls() + success, problems = self.check_conformance(ignore_in_progress=False, is_ci=False, allow_provisional=False) + problem_strs = [str(p) for p in problems] + problem_str = "\n".join(problem_strs) + asserts.assert_equal(success, expect_success_conformance, + f"Improper conformance result for spec version {spec_version:08X}, TC: {tc_enabled} problems: {problem_str}") + + success, problems = self.check_revisions(ignore_in_progress=False) + asserts.assert_equal(success, expect_success_revisions, + f"Improper revision result for spec version {spec_version:08X}, TC: {tc_enabled} problems: {problems}") + + def test_conformance(self): + + # 1.4 is OK if TC is off + self._run_conformance_against_device(0x01040000, False, expect_success_conformance=True, expect_success_revisions=True) + # 1.4.1 is OK if TC is off + self._run_conformance_against_device(0x01040100, False, expect_success_conformance=True, expect_success_revisions=True) + # 1.4.1 is OK if TC is on + self._run_conformance_against_device(0x01040100, True, expect_success_conformance=True, expect_success_revisions=True) + # 1.4 is NOT OK if TC is on + self._run_conformance_against_device(0x01040000, True, expect_success_conformance=False, expect_success_revisions=True) + + # Check that we get a test failure on a bad spec revision + self._create_device(0xFFFFFFFF, False) + with asserts.assert_raises(signals.TestFailure, "Exception not properly raised for bad spec type"): + self.build_spec_xmls() + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TestSpecParsingSupport.py b/src/python_testing/TestSpecParsingSupport.py index 35c1f88d12..ce461f8968 100644 --- a/src/python_testing/TestSpecParsingSupport.py +++ b/src/python_testing/TestSpecParsingSupport.py @@ -253,7 +253,8 @@ def get_access_enum_from_string(access_str: str) -> Clusters.AccessControl.Enums class TestSpecParsingSupport(MatterBaseTest): def setup_class(self): super().setup_class() - self.spec_xml_clusters, self.spec_problems = build_xml_clusters() + # Latest fully certified build + self.spec_xml_clusters, self.spec_problems = build_xml_clusters(PrebuiltDataModelDirectory.k1_4) self.all_spec_clusters = set([(id, c.name, c.pics) for id, c in self.spec_xml_clusters.items()]) def test_build_xml_override(self): diff --git a/src/python_testing/matter_testing_infrastructure/chip/testing/basic_composition.py b/src/python_testing/matter_testing_infrastructure/chip/testing/basic_composition.py index debf902e76..089cec9294 100644 --- a/src/python_testing/matter_testing_infrastructure/chip/testing/basic_composition.py +++ b/src/python_testing/matter_testing_infrastructure/chip/testing/basic_composition.py @@ -31,6 +31,8 @@ import chip.clusters.ClusterObjects import chip.tlv from chip.clusters.Attribute import ValueDecodeFailure +from chip.testing.conformance import ConformanceException +from chip.testing.spec_parsing import PrebuiltDataModelDirectory, build_xml_clusters, build_xml_device_types, dm_from_spec_version from mobly import asserts @@ -210,3 +212,23 @@ def fail_current_test(self, msg: Optional[str] = None): asserts.fail(msg=self.problems[-1].problem) else: asserts.fail(msg) + + def _get_dm(self) -> PrebuiltDataModelDirectory: + try: + spec_version = self.endpoints[0][Clusters.BasicInformation][Clusters.BasicInformation.Attributes.SpecificationVersion] + except KeyError: + asserts.fail( + "Specification Version not found on device - ensure device bas a basic information cluster on EP0 supporting Specification Version") + try: + return dm_from_spec_version(spec_version) + except ConformanceException as e: + asserts.fail(f"Unable to identify specification version: {e}") + + def build_spec_xmls(self): + dm = self._get_dm() + logging.info("----------------------------------------------------------------------------------") + logging.info(f"-- Running tests against Specification version {dm.dirname}") + logging.info("----------------------------------------------------------------------------------") + self.xml_clusters, self.problems = build_xml_clusters(dm) + self.xml_device_types, problems = build_xml_device_types(dm) + self.problems.extend(problems) diff --git a/src/python_testing/matter_testing_infrastructure/chip/testing/matter_testing.py b/src/python_testing/matter_testing_infrastructure/chip/testing/matter_testing.py index 49249cc7da..bac18a7d40 100644 --- a/src/python_testing/matter_testing_infrastructure/chip/testing/matter_testing.py +++ b/src/python_testing/matter_testing_infrastructure/chip/testing/matter_testing.py @@ -803,7 +803,12 @@ def __str__(self): return msg -ProblemLocation = typing.Union[ClusterPathLocation, DeviceTypePathLocation] +class UnknownProblemLocation: + def __str__(self): + return '\n Unknown Locations - see message for more details' + + +ProblemLocation = typing.Union[ClusterPathLocation, DeviceTypePathLocation, UnknownProblemLocation] # ProblemSeverity is not using StrEnum, but rather Enum, since StrEnum only # appeared in 3.11. To make it JSON serializable easily, multiple inheritance diff --git a/src/python_testing/matter_testing_infrastructure/chip/testing/runner.py b/src/python_testing/matter_testing_infrastructure/chip/testing/runner.py index ea06007466..8a773fe647 100644 --- a/src/python_testing/matter_testing_infrastructure/chip/testing/runner.py +++ b/src/python_testing/matter_testing_infrastructure/chip/testing/runner.py @@ -75,6 +75,7 @@ def run_test_with_mock_read(self, read_cache: Attribute.AsyncReadTransaction.Rea self.default_controller.Read = AsyncMock(return_value=read_cache) # This doesn't need to do anything since we are overriding the read anyway self.default_controller.FindOrEstablishPASESession = AsyncMock(return_value=None) + self.default_controller.GetConnectedDevice = AsyncMock(return_value=None) with asyncio.Runner() as runner: return run_tests_no_exit(self.test_class, self.config, runner.get_loop(), hooks, self.default_controller, self.stack) diff --git a/src/python_testing/matter_testing_infrastructure/chip/testing/spec_parsing.py b/src/python_testing/matter_testing_infrastructure/chip/testing/spec_parsing.py index e18df47855..a514c23234 100644 --- a/src/python_testing/matter_testing_infrastructure/chip/testing/spec_parsing.py +++ b/src/python_testing/matter_testing_infrastructure/chip/testing/spec_parsing.py @@ -582,7 +582,7 @@ def get_data_model_directory(data_model_directory: Union[PrebuiltDataModelDirect return path.joinpath(data_model_level.dirname) -def build_xml_clusters(data_model_directory: Union[PrebuiltDataModelDirectory, Traversable] = PrebuiltDataModelDirectory.k1_4_1) -> typing.Tuple[dict[uint, XmlCluster], list[ProblemNotice]]: +def build_xml_clusters(data_model_directory: Union[PrebuiltDataModelDirectory, Traversable]) -> typing.Tuple[dict[uint, XmlCluster], list[ProblemNotice]]: """ Build XML clusters from the specified data model directory. This function supports both pre-built locations and full paths. @@ -851,7 +851,7 @@ def parse_single_device_type(root: ElementTree.Element) -> tuple[dict[int, XmlDe return device_types, problems -def build_xml_device_types(data_model_directory: typing.Union[PrebuiltDataModelDirectory, Traversable] = PrebuiltDataModelDirectory.k1_4_1) -> tuple[dict[int, XmlDeviceType], list[ProblemNotice]]: +def build_xml_device_types(data_model_directory: typing.Union[PrebuiltDataModelDirectory, Traversable]) -> tuple[dict[int, XmlDeviceType], list[ProblemNotice]]: top = get_data_model_directory(data_model_directory, DataModelLevel.kDeviceType) device_types: dict[int, XmlDeviceType] = {} problems: list[ProblemNotice] = [] @@ -881,3 +881,26 @@ def build_xml_device_types(data_model_directory: typing.Union[PrebuiltDataModelD device_types.pop(-1) return device_types, problems + + +def dm_from_spec_version(specification_version: uint) -> PrebuiltDataModelDirectory: + ''' Returns the data model directory for a given specification revision. + + input: specification revision attribute data from the basic information cluster + output: PrebuiltDataModelDirectory + raises: ConformanceException if the given specification_version does not conform to a known data model + ''' + # Specification version attribute is 2 bytes major, 2 bytes minor, 2 bytes dot 2 bytes reserved. + # However, 1.3 allowed the dot to be any value + if specification_version < 0x01040000: + specification_version &= 0xFFFF00FF + + version_to_dm = {0x01030000: PrebuiltDataModelDirectory.k1_3, + 0x01040000: PrebuiltDataModelDirectory.k1_4, + 0x01040100: PrebuiltDataModelDirectory.k1_4_1, + 0x01050000: PrebuiltDataModelDirectory.kMaster} + + if specification_version not in version_to_dm.keys(): + raise ConformanceException(f"Unknown specification_version {specification_version:08X}") + + return version_to_dm[specification_version] diff --git a/src/python_testing/test_metadata.yaml b/src/python_testing/test_metadata.yaml index 850a6ee756..5bd91ecf54 100644 --- a/src/python_testing/test_metadata.yaml +++ b/src/python_testing/test_metadata.yaml @@ -55,6 +55,8 @@ not_automated: reason: Unit test - does not run against an app - name: TestConformanceTest.py reason: Unit test - does not run against an app + - name: TestSpecParsingSelection.py + reason: Unit test - does not run against an app - name: TestMatterTestingSupport.py reason: Unit test - does not run against an app - name: TestSpecParsingSupport.py diff --git a/src/python_testing/test_testing/example_pics_xml_basic_info.xml b/src/python_testing/test_testing/example_pics_xml_basic_info.xml index 3d488c3ae9..b1c3c5347b 100644 --- a/src/python_testing/test_testing/example_pics_xml_basic_info.xml +++ b/src/python_testing/test_testing/example_pics_xml_basic_info.xml @@ -199,6 +199,27 @@ Draft O false + + BINFO.S.A0015 + Does the DUT(server) support the SpecificationVersion attribute? + 9.2.1. Attributes - index.html[pdf] + M + true + + + BINFO.S.A0016 + Does the DUT(server) support the MaxPathsPerInvoke attribute? + 9.2.1. Attributes - index.html[pdf] + M + false + + + BINFO.S.A0017 + Does the DUT(server) support the DeviceLocation attribute? + 9.2.1. Attributes - index.html[pdf] + O + false + diff --git a/src/python_testing/test_testing/test_IDM_10_4.py b/src/python_testing/test_testing/test_IDM_10_4.py index f7e93e9f47..a03be21c34 100644 --- a/src/python_testing/test_testing/test_IDM_10_4.py +++ b/src/python_testing/test_testing/test_IDM_10_4.py @@ -49,6 +49,7 @@ def create_read(include_reachable: bool = False, include_max_paths: bool = False bi.ProductLabel: 'myProduct', bi.SerialNumber: 'ABCD1234', bi.LocalConfigDisabled: False, + bi.SpecificationVersion: 0x01040000, bi.UniqueID: 'Hashy-McHashface'} if include_reachable: attrs_bi[bi.Reachable] = True From cbe17edd234291c51f344338b6b32332fcad8179 Mon Sep 17 00:00:00 2001 From: Nivi Sarkar <55898241+nivi-apple@users.noreply.github.com> Date: Thu, 6 Feb 2025 16:17:01 -0800 Subject: [PATCH 15/39] =?UTF-8?q?Reduce=20logging=20in=20BDXTransferSessio?= =?UTF-8?q?n=20by=20removing=20logging=20for=20BlockQue=E2=80=A6=20(#37412?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Reduce logging in BDXTransferSession by removing logging for BlockQuery, Block and BlockAck messages as they generate a lot of logs - The Exchange Manager alreadys logs the BlockQuery, Block and BlockAck messages and that can be used for debugging purposes - Do not log messages for OutputEvent when the event type is None - Also reduce additional logging in the darwin code. * Restyle * Address review comments * Fix whitespace restyled issue. --------- Co-authored-by: Boris Zbarsky --- .../CHIP/MTROTAImageTransferHandler.mm | 2 +- .../bdx/AsyncTransferFacilitator.cpp | 5 +- src/protocols/bdx/BdxTransferSession.cpp | 57 ++++++------------- 3 files changed, 20 insertions(+), 44 deletions(-) diff --git a/src/darwin/Framework/CHIP/MTROTAImageTransferHandler.mm b/src/darwin/Framework/CHIP/MTROTAImageTransferHandler.mm index efa84ef916..6a6dce94df 100644 --- a/src/darwin/Framework/CHIP/MTROTAImageTransferHandler.mm +++ b/src/darwin/Framework/CHIP/MTROTAImageTransferHandler.mm @@ -310,7 +310,7 @@ - (instancetype)initWithMTROTAImageTransferHandler:(MTROTAImageTransferHandler * TransferSession::OutputEventType eventType = event.EventType; - ChipLogError(BDX, "OutputEvent type: %s", event.ToString(eventType)); + ChipLogDetail(BDX, "OutputEvent type: %s", event.ToString(eventType)); CHIP_ERROR err = CHIP_NO_ERROR; switch (event.EventType) { diff --git a/src/protocols/bdx/AsyncTransferFacilitator.cpp b/src/protocols/bdx/AsyncTransferFacilitator.cpp index eb3d996b1e..94cb3f1f3c 100644 --- a/src/protocols/bdx/AsyncTransferFacilitator.cpp +++ b/src/protocols/bdx/AsyncTransferFacilitator.cpp @@ -178,9 +178,6 @@ CHIP_ERROR AsyncResponder::Init(System::Layer * layer, Messaging::ExchangeContex void AsyncResponder::NotifyEventHandled(const TransferSession::OutputEventType eventType, CHIP_ERROR status) { - ChipLogDetail(BDX, "NotifyEventHandled : Event %s Error %" CHIP_ERROR_FORMAT, - TransferSession::OutputEvent::TypeToString(eventType), status.Format()); - // If this is the end of the transfer (whether a clean end, or some sort of error condition), ensure // that we destroy ourselves after unwinding the processing loop in the ProcessOutputEvents API. // We can ignore the status for these output events because none of them are supposed to result in @@ -194,6 +191,8 @@ void AsyncResponder::NotifyEventHandled(const TransferSession::OutputEventType e eventType == TransferSession::OutputEventType::kTransferTimeout || eventType == TransferSession::OutputEventType::kStatusReceived) { + ChipLogProgress(BDX, "NotifyEventHandled : Event %s Error %" CHIP_ERROR_FORMAT, + TransferSession::OutputEvent::TypeToString(eventType), status.Format()); mDestroySelfAfterProcessingEvents = true; } else if (status != CHIP_NO_ERROR) diff --git a/src/protocols/bdx/BdxTransferSession.cpp b/src/protocols/bdx/BdxTransferSession.cpp index fdf9bb2c84..c2715ef1b0 100644 --- a/src/protocols/bdx/BdxTransferSession.cpp +++ b/src/protocols/bdx/BdxTransferSession.cpp @@ -291,11 +291,6 @@ CHIP_ERROR TransferSession::PrepareBlockQuery() ReturnErrorOnFailure(WriteToPacketBuffer(queryMsg, mPendingMsgHandle)); -#if CHIP_AUTOMATION_LOGGING - ChipLogAutomation("Sending BDX Message"); - queryMsg.LogMessage(msgType); -#endif // CHIP_AUTOMATION_LOGGING - mAwaitingResponse = true; mLastQueryNum = mNextQueryNum++; @@ -319,11 +314,6 @@ CHIP_ERROR TransferSession::PrepareBlockQueryWithSkip(const uint64_t & bytesToSk ReturnErrorOnFailure(WriteToPacketBuffer(queryMsg, mPendingMsgHandle)); -#if CHIP_AUTOMATION_LOGGING - ChipLogAutomation("Sending BDX Message"); - queryMsg.LogMessage(msgType); -#endif // CHIP_AUTOMATION_LOGGING - mAwaitingResponse = true; mLastQueryNum = mNextQueryNum++; @@ -351,13 +341,12 @@ CHIP_ERROR TransferSession::PrepareBlock(const BlockData & inData) const MessageType msgType = inData.IsEof ? MessageType::BlockEOF : MessageType::Block; -#if CHIP_AUTOMATION_LOGGING - ChipLogAutomation("Sending BDX Message"); - blockMsg.LogMessage(msgType); -#endif // CHIP_AUTOMATION_LOGGING - if (msgType == MessageType::BlockEOF) { +#if CHIP_AUTOMATION_LOGGING + ChipLogAutomation("Sending BDX Message"); + blockMsg.LogMessage(msgType); +#endif // CHIP_AUTOMATION_LOGGING mState = TransferState::kAwaitingEOFAck; } @@ -382,11 +371,6 @@ CHIP_ERROR TransferSession::PrepareBlockAck() ReturnErrorOnFailure(WriteToPacketBuffer(ackMsg, mPendingMsgHandle)); -#if CHIP_AUTOMATION_LOGGING - ChipLogAutomation("Sending BDX Message"); - ackMsg.LogMessage(msgType); -#endif // CHIP_AUTOMATION_LOGGING - if (mState == TransferState::kTransferInProgress) { if (mControlMode == TransferControlFlags::kSenderDrive) @@ -399,6 +383,10 @@ CHIP_ERROR TransferSession::PrepareBlockAck() } else if (mState == TransferState::kReceivedEOF) { +#if CHIP_AUTOMATION_LOGGING + ChipLogAutomation("Sending BDX Message"); + ackMsg.LogMessage(msgType); +#endif // CHIP_AUTOMATION_LOGGING mState = TransferState::kTransferDone; mAwaitingResponse = false; } @@ -475,20 +463,25 @@ CHIP_ERROR TransferSession::HandleBdxMessage(const PayloadHeader & header, Syste const MessageType msgType = static_cast(header.GetMessageType()); -#if CHIP_AUTOMATION_LOGGING - ChipLogAutomation("Handling received BDX Message"); -#endif // CHIP_AUTOMATION_LOGGING - switch (msgType) { case MessageType::SendInit: case MessageType::ReceiveInit: +#if CHIP_AUTOMATION_LOGGING + ChipLogAutomation("Handling received BDX Message"); +#endif // CHIP_AUTOMATION_LOGGING HandleTransferInit(msgType, std::move(msg)); break; case MessageType::SendAccept: +#if CHIP_AUTOMATION_LOGGING + ChipLogAutomation("Handling received BDX Message"); +#endif // CHIP_AUTOMATION_LOGGING HandleSendAccept(std::move(msg)); break; case MessageType::ReceiveAccept: +#if CHIP_AUTOMATION_LOGGING + ChipLogAutomation("Handling received BDX Message"); +#endif // CHIP_AUTOMATION_LOGGING HandleReceiveAccept(std::move(msg)); break; case MessageType::BlockQuery: @@ -672,10 +665,6 @@ void TransferSession::HandleBlockQuery(System::PacketBufferHandle msgData) mAwaitingResponse = false; mLastQueryNum = query.BlockCounter; - -#if CHIP_AUTOMATION_LOGGING - query.LogMessage(MessageType::BlockQuery); -#endif // CHIP_AUTOMATION_LOGGING } void TransferSession::HandleBlockQueryWithSkip(System::PacketBufferHandle msgData) @@ -695,10 +684,6 @@ void TransferSession::HandleBlockQueryWithSkip(System::PacketBufferHandle msgDat mAwaitingResponse = false; mLastQueryNum = query.BlockCounter; mBytesToSkip.BytesToSkip = query.BytesToSkip; - -#if CHIP_AUTOMATION_LOGGING - query.LogMessage(MessageType::BlockQueryWithSkip); -#endif // CHIP_AUTOMATION_LOGGING } void TransferSession::HandleBlock(System::PacketBufferHandle msgData) @@ -733,10 +718,6 @@ void TransferSession::HandleBlock(System::PacketBufferHandle msgData) mLastBlockNum = blockMsg.BlockCounter; mAwaitingResponse = false; - -#if CHIP_AUTOMATION_LOGGING - blockMsg.LogMessage(MessageType::Block); -#endif // CHIP_AUTOMATION_LOGGING } void TransferSession::HandleBlockEOF(System::PacketBufferHandle msgData) @@ -787,10 +768,6 @@ void TransferSession::HandleBlockAck(System::PacketBufferHandle msgData) // In Receiver Drive, the Receiver can send a BlockAck to indicate receipt of the message and reset the timeout. // In this case, the Sender should wait to receive a BlockQuery next. mAwaitingResponse = (mControlMode == TransferControlFlags::kReceiverDrive); - -#if CHIP_AUTOMATION_LOGGING - ackMsg.LogMessage(MessageType::BlockAck); -#endif // CHIP_AUTOMATION_LOGGING } void TransferSession::HandleBlockAckEOF(System::PacketBufferHandle msgData) From ce47e220186e2d979c0a613d6c57003c7fc3d66a Mon Sep 17 00:00:00 2001 From: Shreyas Balakrishna Bhandare Date: Thu, 6 Feb 2025 17:27:55 -0800 Subject: [PATCH 16/39] Create an AAI registry for PwRPC services to allow registration of custom AAI classes (#37351) * Allow custom AAI registration for PwRPC Reads/Writes. Update PwRPC Writes to look for custom AAIs before using datamodel provider * Add succes log * Make TryWriteViaAAI public * Make TryWriteViaAAI public * Fix compilation errors * Fix compilation errors * Fix compilation errors * Update examples/common/pigweed/rpc_services/Attributes.h Co-authored-by: Tennessee Carmel-Veilleux * Add new attribute accessor and registry for PwRPC * Fix compilation error * Fix compilation error * Fix compilation error * Revert changes * Revert changes * Accessors will not be indexed by EndpointId/ClusterId. Caller queries all accessors to satisfy the request and returns as soon as a succes/failure is encountered. Accessors will return 'pw::Status::NotFound()' as a way of hinting the caller 'look for an alternative'. If no accessors were registered or all returned 'NotFound' the fallback path is taken. * fix compilation bug * Review comments * Fix compilation * Fix nits * Fix ESP32 compilation * Update examples/common/pigweed/rpc_services/AccessInterceptor.h Nit : rename parameter names. Co-authored-by: Andrei Litvin * Update examples/common/pigweed/rpc_services/AccessInterceptor.h Review suggestion. Co-authored-by: Andrei Litvin * Update examples/common/pigweed/rpc_services/AccessInterceptorRegistry.h Review suggestion. Co-authored-by: Andrei Litvin * Review comments * Update examples/common/pigweed/rpc_services/AccessInterceptor.h --------- Co-authored-by: Tennessee Carmel-Veilleux Co-authored-by: Andrei Litvin --- .../pigweed/rpc_services/AccessInterceptor.h | 55 ++++++++++++++ .../rpc_services/AccessInterceptorRegistry.h | 73 +++++++++++++++++++ .../common/pigweed/rpc_services/Attributes.h | 36 +++++++++ 3 files changed, 164 insertions(+) create mode 100644 examples/common/pigweed/rpc_services/AccessInterceptor.h create mode 100644 examples/common/pigweed/rpc_services/AccessInterceptorRegistry.h diff --git a/examples/common/pigweed/rpc_services/AccessInterceptor.h b/examples/common/pigweed/rpc_services/AccessInterceptor.h new file mode 100644 index 0000000000..c63adcef8d --- /dev/null +++ b/examples/common/pigweed/rpc_services/AccessInterceptor.h @@ -0,0 +1,55 @@ +/* + * + * Copyright (c) 2025 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "pw_status/status.h" +#include +#include +#include + +namespace chip { +namespace rpc { + +/** + * Callback class that clusters can implement in order to interpose custom + * interception logic. + */ +class PigweedDebugAccessInterceptor +{ +public: + PigweedDebugAccessInterceptor() = default; + virtual ~PigweedDebugAccessInterceptor() = default; + + /** + * Callback for writing attributes. + * + * The implementation can do one of three things: + * + * Returns: + * - `std::nullopt` if the `path` was not handled by this Interceptor. + * Interceptor MUST NOT have attepted to decode `decoder`. + * - A `::pw::Status` value that is considered the FINAL result of the + * write (i.e. write handled) either with success or failure. + */ + virtual std::optional<::pw::Status> Write(const chip::app::ConcreteDataAttributePath & path, + chip::app::AttributeValueDecoder & decoder) = 0; +}; + +} // namespace rpc +} // namespace chip diff --git a/examples/common/pigweed/rpc_services/AccessInterceptorRegistry.h b/examples/common/pigweed/rpc_services/AccessInterceptorRegistry.h new file mode 100644 index 0000000000..bc0a6aeb09 --- /dev/null +++ b/examples/common/pigweed/rpc_services/AccessInterceptorRegistry.h @@ -0,0 +1,73 @@ +/* + * + * Copyright (c) 2025 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "pw_status/status.h" +#include +#include + +namespace chip { +namespace rpc { + +/** @brief Custom debug request interceptors. + * + * This class is specifically meant for registering custom Accessors that + * allow mini-handlers to process PigweedRPC read/writes separately from the cluster + * code. It is meant to be used by samples using this PigweedRPC services to allow the RPC + * interface to be used in more ways than simply for example, simulating writes from a Matter + * client at the IM level. Handlers registered here by applications should be attempted before any + * standard processing. + */ +class PigweedDebugAccessInterceptorRegistry +{ +public: + /** + * Registers an attribute access inteceptor within this registry. Use `Unregister` to + * unregister an interceptor that was previously registered. + * @param attrOverride - the interceptor to be registered. + */ + void Register(PigweedDebugAccessInterceptor * attrOverride) { mAccessors.insert(attrOverride); } + + void Unregister(PigweedDebugAccessInterceptor * attrOverride) + { + if (mAccessors.find(attrOverride) == mAccessors.end()) + { + ChipLogError(Support, "Attempt to unregister accessor that is not registered."); + return; + } + mAccessors.erase(attrOverride); + } + + const std::set & GetAllAccessors() const { return mAccessors; } + + /** + * Returns the singleton instance of the attribute accessor registory. + */ + static PigweedDebugAccessInterceptorRegistry & Instance() + { + static PigweedDebugAccessInterceptorRegistry instance; + return instance; + } + +private: + std::set mAccessors; +}; + +} // namespace rpc +} // namespace chip diff --git a/examples/common/pigweed/rpc_services/Attributes.h b/examples/common/pigweed/rpc_services/Attributes.h index eff2af5d66..9ac206f712 100644 --- a/examples/common/pigweed/rpc_services/Attributes.h +++ b/examples/common/pigweed/rpc_services/Attributes.h @@ -33,14 +33,42 @@ #include #include #include +#include #include #include #include +#include +#include #include +#include namespace chip { namespace rpc { +std::optional<::pw::Status> TryWriteViaAccessor(const chip::app::ConcreteDataAttributePath & path, + chip::app::AttributeValueDecoder & decoder) +{ + std::set accessors = PigweedDebugAccessInterceptorRegistry::Instance().GetAllAccessors(); + + for (PigweedDebugAccessInterceptor * accessor : accessors) + { + std::optional<::pw::Status> result = accessor->Write(path, decoder); + if (result.has_value()) // Write was either a success or failure. + { + return result; + } + else if (decoder.TriedDecode()) + { + ChipLogError(Support, "Interceptor tried decode but did not return status."); + return ::pw::Status::FailedPrecondition(); + } + } + + VerifyOrReturnError(!decoder.TriedDecode(), ::pw::Status::FailedPrecondition()); + + return std::nullopt; +} + // Implementation class for chip.rpc.Attributes. class Attributes : public pw_rpc::nanopb::Attributes::Service { @@ -207,6 +235,14 @@ class Attributes : public pw_rpc::nanopb::Attributes::Service } app::AttributeValueDecoder decoder(tlvReader.value(), subjectDescriptor); + + std::optional<::pw::Status> interceptResult = TryWriteViaAccessor(write_request.path, decoder); + if (interceptResult.has_value()) + { + return *interceptResult; + } + ChipLogProgress(Support, "No custom PigweedRPC Attribute Accessor registration found, using fake write access."); + app::DataModel::ActionReturnStatus result = provider->WriteAttribute(write_request, decoder); if (!result.IsSuccess()) From e1d26a08fbf80c49f3b782081140c5ffd0ec0514 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Thu, 6 Feb 2025 23:00:13 -0500 Subject: [PATCH 17/39] Fix validation of return value for invokeCommands. (#37442) The response array for this case can have any number of entries, not just one. --- .../Framework/CHIP/MTRDeviceDataValidation.h | 5 ++ .../Framework/CHIP/MTRDeviceDataValidation.mm | 73 ++++++++++++------- src/darwin/Framework/CHIP/MTRDevice_XPC.mm | 2 +- .../Framework/CHIPTests/MTRDeviceTests.m | 7 ++ 4 files changed, 58 insertions(+), 29 deletions(-) diff --git a/src/darwin/Framework/CHIP/MTRDeviceDataValidation.h b/src/darwin/Framework/CHIP/MTRDeviceDataValidation.h index 5d448d8aa4..72ee6f4679 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceDataValidation.h +++ b/src/darwin/Framework/CHIP/MTRDeviceDataValidation.h @@ -39,4 +39,9 @@ MTR_EXTERN MTR_TESTABLE BOOL MTREventReportIsWellFormed(NSArray * response); +// Returns whether the provided invoke reponses actually has the right sorts of +// objects in the right places. This differes from +// MTRInvokeResponseIsWellFormed in not enforcing that there is only one response. +MTR_EXTERN MTR_TESTABLE BOOL MTRInvokeResponsesAreWellFormed(NSArray * response); + NS_ASSUME_NONNULL_END diff --git a/src/darwin/Framework/CHIP/MTRDeviceDataValidation.mm b/src/darwin/Framework/CHIP/MTRDeviceDataValidation.mm index 838f33d093..ba71a80717 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceDataValidation.mm +++ b/src/darwin/Framework/CHIP/MTRDeviceDataValidation.mm @@ -165,51 +165,68 @@ BOOL MTREventReportIsWellFormed(NSArray * repo BOOL MTRInvokeResponseIsWellFormed(NSArray * response) { - if (!MTR_SAFE_CAST(response, NSArray)) { - MTR_LOG_ERROR("Invoke response is not an array: %@", response); + if (!MTRInvokeResponsesAreWellFormed(response)) { return NO; } - // Input is an array with a single value that must have MTRCommandPathKey. + // Input is an array with a single value. if (response.count != 1) { MTR_LOG_ERROR("Invoke response is not an array with exactly one entry: %@", response); return NO; } - MTRDeviceResponseValueDictionary responseValue = response[0]; + return YES; +} - if (!MTR_SAFE_CAST(responseValue, NSDictionary) || !MTR_SAFE_CAST(responseValue[MTRCommandPathKey], MTRCommandPath)) { - MTR_LOG_ERROR("Invoke response is not an array with the right things in it: %@", response); +BOOL MTRInvokeResponsesAreWellFormed(NSArray * response) +{ + if (!MTR_SAFE_CAST(response, NSArray)) { + MTR_LOG_ERROR("Invoke response is not an array: %@", response); return NO; } - MTRDeviceDataValueDictionary _Nullable data = responseValue[MTRDataKey]; - NSError * _Nullable error = responseValue[MTRErrorKey]; + for (MTRDeviceResponseValueDictionary responseValue in response) { + // Each entry must be a dictionary that has MTRCommandPathKey. - if (data != nil && error != nil) { - MTR_LOG_ERROR("Invoke response claims to have both data and error: %@", responseValue); - return NO; - } + if (!MTR_SAFE_CAST(responseValue, NSDictionary) || !MTR_SAFE_CAST(responseValue[MTRCommandPathKey], MTRCommandPath)) { + MTR_LOG_ERROR("Invoke response has an invalid array entry: %@", responseValue); + return NO; + } - if (error != nil) { - return MTR_SAFE_CAST(error, NSError) != nil; - } + MTRDeviceDataValueDictionary _Nullable data = responseValue[MTRDataKey]; + NSError * _Nullable error = responseValue[MTRErrorKey]; - if (data == nil) { - // This is valid: indicates a success status response. - return YES; - } + if (data != nil && error != nil) { + MTR_LOG_ERROR("Invoke response claims to have both data and error: %@", responseValue); + return NO; + } - if (!MTRDataValueDictionaryIsWellFormed(data)) { - MTR_LOG_ERROR("Invoke response claims to have data that is not a data-value: %@", data); - return NO; - } + if (error != nil) { + if (!MTR_SAFE_CAST(error, NSError)) { + MTR_LOG_ERROR("Invoke response %@ has %@ instead of an NSError", responseValue, error); + return NO; + } - // Now we know data is a dictionary (in fact a data-value). The only thing - // we promise about it is that it has type MTRStructureValueType. - if (![MTRStructureValueType isEqual:data[MTRTypeKey]]) { - MTR_LOG_ERROR("Invoke response data is not of structure type: %@", data); - return NO; + // Valid error response. + continue; + } + + if (data == nil) { + // This is valid: indicates a success status response. + continue; + } + + if (!MTRDataValueDictionaryIsWellFormed(data)) { + MTR_LOG_ERROR("Invoke response claims to have data that is not a data-value: %@", data); + return NO; + } + + // Now we know data is a dictionary (in fact a data-value). The only thing + // we promise about it is that it has type MTRStructureValueType. + if (![MTRStructureValueType isEqual:data[MTRTypeKey]]) { + MTR_LOG_ERROR("Invoke response data is not of structure type: %@", data); + return NO; + } } return YES; diff --git a/src/darwin/Framework/CHIP/MTRDevice_XPC.mm b/src/darwin/Framework/CHIP/MTRDevice_XPC.mm index 31cf082876..fed4238f6b 100644 --- a/src/darwin/Framework/CHIP/MTRDevice_XPC.mm +++ b/src/darwin/Framework/CHIP/MTRDevice_XPC.mm @@ -488,7 +488,7 @@ - (void)invokeCommands:(NSArray *> *)c return; } - if (responses != nil && !MTRInvokeResponseIsWellFormed(responses)) { + if (responses != nil && !MTRInvokeResponsesAreWellFormed(responses)) { MTR_LOG_ERROR("%@ got invoke responses for %@ that has invalid data: %@", self, commands, responses); completion(nil, [MTRError errorForCHIPErrorCode:CHIP_ERROR_INVALID_ARGUMENT]); return; diff --git a/src/darwin/Framework/CHIPTests/MTRDeviceTests.m b/src/darwin/Framework/CHIPTests/MTRDeviceTests.m index 71f6aa29fb..7184e434a4 100644 --- a/src/darwin/Framework/CHIPTests/MTRDeviceTests.m +++ b/src/darwin/Framework/CHIPTests/MTRDeviceTests.m @@ -5752,6 +5752,7 @@ - (void)test045_MTRDeviceInvokeGroups completion:^(NSArray *> * _Nullable values, NSError * _Nullable error) { XCTAssertNil(error); XCTAssertNotNil(values); + XCTAssertTrue(MTRInvokeResponsesAreWellFormed(values)); // Successful invoke is represented as a value with the relevant // command path and neither data nor error. @@ -5781,6 +5782,7 @@ - (void)test045_MTRDeviceInvokeGroups completion:^(NSArray *> * _Nullable values, NSError * _Nullable error) { XCTAssertNil(error); XCTAssertNotNil(values); + XCTAssertTrue(MTRInvokeResponsesAreWellFormed(values)); // We should not have anything for groups after the first one XCTAssertEqual(values.count, 2); @@ -5814,6 +5816,7 @@ - (void)test045_MTRDeviceInvokeGroups completion:^(NSArray *> * _Nullable values, NSError * _Nullable error) { XCTAssertNil(error); XCTAssertNotNil(values); + XCTAssertTrue(MTRInvokeResponsesAreWellFormed(values)); // We should not have anything for groups after the first one __auto_type * expectedValues = @[ @@ -5858,6 +5861,7 @@ - (void)test045_MTRDeviceInvokeGroups completion:^(NSArray *> * _Nullable values, NSError * _Nullable error) { XCTAssertNil(error); XCTAssertNotNil(values); + XCTAssertTrue(MTRInvokeResponsesAreWellFormed(values)); XCTAssertEqual(values.count, 3); @@ -5902,6 +5906,7 @@ - (void)test045_MTRDeviceInvokeGroups completion:^(NSArray *> * _Nullable values, NSError * _Nullable error) { XCTAssertNil(error); XCTAssertNotNil(values); + XCTAssertTrue(MTRInvokeResponsesAreWellFormed(values)); XCTAssertEqual(values.count, 3); @@ -5946,6 +5951,7 @@ - (void)test045_MTRDeviceInvokeGroups completion:^(NSArray *> * _Nullable values, NSError * _Nullable error) { XCTAssertNil(error); XCTAssertNotNil(values); + XCTAssertTrue(MTRInvokeResponsesAreWellFormed(values)); XCTAssertEqual(values.count, 2); @@ -5988,6 +5994,7 @@ - (void)test045_MTRDeviceInvokeGroups completion:^(NSArray *> * _Nullable values, NSError * _Nullable error) { XCTAssertNil(error); XCTAssertNotNil(values); + XCTAssertTrue(MTRInvokeResponsesAreWellFormed(values)); XCTAssertEqual(values.count, 2); From 2a77a116fe5234a14e7578933459fa76f240cd6e Mon Sep 17 00:00:00 2001 From: yunhanw-google Date: Thu, 6 Feb 2025 21:35:55 -0800 Subject: [PATCH 18/39] Revert "[Java] Delete finalize method in java (#37417)" (#37446) This reverts commit d777dce30baad3b5298346b6a1661b9a78c8a6ff. --- .../generators/java/ChipClusters_java.jinja | 23 +++++------ .../several_clusters/java/ChipClusters.java | 23 +++++------ .../chip/devicecontroller/ChipClusters.java | 23 +++++------ .../BatchInvokeCallbackJni.java | 39 +++++++++---------- .../ChipDeviceController.java | 24 +++++------- .../ExtendableInvokeCallbackJni.java | 25 ++++++------ .../GetConnectedDeviceCallbackJni.java | 26 ++++++------- .../devicecontroller/InvokeCallbackJni.java | 25 ++++++------ .../devicecontroller/ReportCallbackJni.java | 25 ++++++------ .../WriteAttributesCallbackJni.java | 25 ++++++------ 10 files changed, 110 insertions(+), 148 deletions(-) diff --git a/scripts/py_matter_idl/matter_idl/generators/java/ChipClusters_java.jinja b/scripts/py_matter_idl/matter_idl/generators/java/ChipClusters_java.jinja index dd2627221c..954bd7de57 100644 --- a/scripts/py_matter_idl/matter_idl/generators/java/ChipClusters_java.jinja +++ b/scripts/py_matter_idl/matter_idl/generators/java/ChipClusters_java.jinja @@ -105,7 +105,6 @@ import chip.devicecontroller.model.NodeState; import chip.devicecontroller.model.Status; import javax.annotation.Nullable; -import java.lang.ref.Cleaner; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -170,23 +169,10 @@ public class ChipClusters { private Optional timeoutMillis = Optional.empty(); - private final Cleaner.Cleanable cleanable; - public BaseChipCluster(long devicePtr, int endpointId, long clusterId) { this.devicePtr = devicePtr; this.endpointId = endpointId; this.clusterId = clusterId; - - this.cleanable = - Cleaner.create() - .register( - this, - () -> { - if (chipClusterPtr != 0) { - deleteCluster(chipClusterPtr); - chipClusterPtr = 0; - } - }); } /** @@ -255,6 +241,15 @@ public class ChipClusters { @Deprecated public void deleteCluster(long chipClusterPtr) {} + @SuppressWarnings("deprecation") + protected void finalize() throws Throwable { + super.finalize(); + + if (chipClusterPtr != 0) { + deleteCluster(chipClusterPtr); + chipClusterPtr = 0; + } + } } abstract static class ReportCallbackImpl implements ReportCallback, SubscriptionEstablishedCallback, ResubscriptionAttemptCallback { diff --git a/scripts/py_matter_idl/matter_idl/tests/outputs/several_clusters/java/ChipClusters.java b/scripts/py_matter_idl/matter_idl/tests/outputs/several_clusters/java/ChipClusters.java index 997631bb47..037870ee20 100644 --- a/scripts/py_matter_idl/matter_idl/tests/outputs/several_clusters/java/ChipClusters.java +++ b/scripts/py_matter_idl/matter_idl/tests/outputs/several_clusters/java/ChipClusters.java @@ -28,7 +28,6 @@ import chip.devicecontroller.model.Status; import javax.annotation.Nullable; -import java.lang.ref.Cleaner; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -93,23 +92,10 @@ public static abstract class BaseChipCluster { private Optional timeoutMillis = Optional.empty(); - private final Cleaner.Cleanable cleanable; - public BaseChipCluster(long devicePtr, int endpointId, long clusterId) { this.devicePtr = devicePtr; this.endpointId = endpointId; this.clusterId = clusterId; - - this.cleanable = - Cleaner.create() - .register( - this, - () -> { - if (chipClusterPtr != 0) { - deleteCluster(chipClusterPtr); - chipClusterPtr = 0; - } - }); } /** @@ -178,6 +164,15 @@ protected void invoke( @Deprecated public void deleteCluster(long chipClusterPtr) {} + @SuppressWarnings("deprecation") + protected void finalize() throws Throwable { + super.finalize(); + + if (chipClusterPtr != 0) { + deleteCluster(chipClusterPtr); + chipClusterPtr = 0; + } + } } abstract static class ReportCallbackImpl implements ReportCallback, SubscriptionEstablishedCallback, ResubscriptionAttemptCallback { diff --git a/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java b/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java index b41b847b1e..da6e6e5c7d 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java @@ -28,7 +28,6 @@ import chip.devicecontroller.model.Status; import javax.annotation.Nullable; -import java.lang.ref.Cleaner; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -93,23 +92,10 @@ public static abstract class BaseChipCluster { private Optional timeoutMillis = Optional.empty(); - private final Cleaner.Cleanable cleanable; - public BaseChipCluster(long devicePtr, int endpointId, long clusterId) { this.devicePtr = devicePtr; this.endpointId = endpointId; this.clusterId = clusterId; - - this.cleanable = - Cleaner.create() - .register( - this, - () -> { - if (chipClusterPtr != 0) { - deleteCluster(chipClusterPtr); - chipClusterPtr = 0; - } - }); } /** @@ -178,6 +164,15 @@ protected void invoke( @Deprecated public void deleteCluster(long chipClusterPtr) {} + @SuppressWarnings("deprecation") + protected void finalize() throws Throwable { + super.finalize(); + + if (chipClusterPtr != 0) { + deleteCluster(chipClusterPtr); + chipClusterPtr = 0; + } + } } abstract static class ReportCallbackImpl implements ReportCallback, SubscriptionEstablishedCallback, ResubscriptionAttemptCallback { diff --git a/src/controller/java/src/chip/devicecontroller/BatchInvokeCallbackJni.java b/src/controller/java/src/chip/devicecontroller/BatchInvokeCallbackJni.java index f873ce6add..6982f58429 100644 --- a/src/controller/java/src/chip/devicecontroller/BatchInvokeCallbackJni.java +++ b/src/controller/java/src/chip/devicecontroller/BatchInvokeCallbackJni.java @@ -19,31 +19,17 @@ import chip.devicecontroller.model.InvokeResponseData; import chip.devicecontroller.model.NoInvokeResponseData; -import java.lang.ref.Cleaner; import java.util.Optional; import javax.annotation.Nullable; /** JNI wrapper callback class for {@link InvokeCallback}. */ -public final class BatchInvokeCallbackJni { - private final BatchInvokeCallbackJni wrappedBatchInvokeCallback; +public final class ExtendableInvokeCallbackJni { + private final ExtendableInvokeCallback wrappedExtendableInvokeCallback; private long callbackHandle; - private final Cleaner.Cleanable cleanable; - - public BatchInvokeCallbackJni(BatchInvokeCallback wrappedBatchInvokeCallback) { - this.wrappedBatchInvokeCallback = wrappedBatchInvokeCallback; + public ExtendableInvokeCallbackJni(ExtendableInvokeCallback wrappedExtendableInvokeCallback) { + this.wrappedExtendableInvokeCallback = wrappedExtendableInvokeCallback; this.callbackHandle = newCallback(); - - this.cleanable = - Cleaner.create() - .register( - this, - () -> { - if (chipClusterPtr != 0) { - deleteCluster(chipClusterPtr); - chipClusterPtr = 0; - } - }); } long getCallbackHandle() { @@ -55,7 +41,7 @@ long getCallbackHandle() { private native void deleteCallback(long callbackHandle); private void onError(Exception e) { - wrappedBatchInvokeCallback.onError(e); + wrappedExtendableInvokeCallback.onError(e); } private void onResponse( @@ -88,10 +74,21 @@ private void onResponse( } private void onNoResponse(int commandRef) { - wrappedBatchInvokeCallback.onNoResponse(NoInvokeResponseData.newInstance(commandRef)); + wrappedExtendableInvokeCallback.onNoResponse(NoInvokeResponseData.newInstance(commandRef)); } private void onDone() { - wrappedBatchInvokeCallback.onDone(); + wrappedExtendableInvokeCallback.onDone(); + } + + // TODO(#8578): Replace finalizer with PhantomReference. + @SuppressWarnings("deprecation") + protected void finalize() throws Throwable { + super.finalize(); + + if (callbackHandle != 0) { + deleteCallback(callbackHandle); + callbackHandle = 0; + } } } diff --git a/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java b/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java index 893307be21..c324948974 100644 --- a/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java +++ b/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java @@ -26,7 +26,6 @@ import chip.devicecontroller.model.ChipEventPath; import chip.devicecontroller.model.DataVersionFilter; import chip.devicecontroller.model.InvokeElement; -import java.lang.ref.Cleaner; import java.time.ZoneOffset; import java.util.ArrayList; import java.util.Calendar; @@ -45,8 +44,6 @@ public class ChipDeviceController { private ScanNetworksListener scanNetworksListener; private NOCChainIssuer nocChainIssuer; - private final Cleaner.Cleanable cleanable; - /** * To load class and jni, we need to new AndroidChipPlatform after jni load but before new * ChipDeviceController @@ -70,17 +67,6 @@ public ChipDeviceController(ControllerParams params) { throw new NullPointerException("params cannot be null"); } deviceControllerPtr = newDeviceController(params); - - this.cleanable = - Cleaner.create() - .register( - this, - () -> { - if (deviceControllerPtr != 0) { - deleteDeviceController(deviceControllerPtr); - deviceControllerPtr = 0; - } - }); } public void setCompletionListener(CompletionListener listener) { @@ -1787,6 +1773,16 @@ private native void updateCommissioningICDRegistrationInfo( System.loadLibrary("CHIPController"); } + @SuppressWarnings("deprecation") + protected void finalize() throws Throwable { + super.finalize(); + + if (deviceControllerPtr != 0) { + deleteDeviceController(deviceControllerPtr); + deviceControllerPtr = 0; + } + } + /** Interface to implement custom operational credentials issuer (NOC chain generation). */ public interface NOCChainIssuer { /** diff --git a/src/controller/java/src/chip/devicecontroller/ExtendableInvokeCallbackJni.java b/src/controller/java/src/chip/devicecontroller/ExtendableInvokeCallbackJni.java index 6c12940fb6..6982f58429 100644 --- a/src/controller/java/src/chip/devicecontroller/ExtendableInvokeCallbackJni.java +++ b/src/controller/java/src/chip/devicecontroller/ExtendableInvokeCallbackJni.java @@ -19,7 +19,6 @@ import chip.devicecontroller.model.InvokeResponseData; import chip.devicecontroller.model.NoInvokeResponseData; -import java.lang.ref.Cleaner; import java.util.Optional; import javax.annotation.Nullable; @@ -28,22 +27,9 @@ public final class ExtendableInvokeCallbackJni { private final ExtendableInvokeCallback wrappedExtendableInvokeCallback; private long callbackHandle; - private final Cleaner.Cleanable cleanable; - public ExtendableInvokeCallbackJni(ExtendableInvokeCallback wrappedExtendableInvokeCallback) { this.wrappedExtendableInvokeCallback = wrappedExtendableInvokeCallback; this.callbackHandle = newCallback(); - - this.cleanable = - Cleaner.create() - .register( - this, - () -> { - if (callbackHandle != 0) { - deleteCallback(callbackHandle); - callbackHandle = 0; - } - }); } long getCallbackHandle() { @@ -94,4 +80,15 @@ private void onNoResponse(int commandRef) { private void onDone() { wrappedExtendableInvokeCallback.onDone(); } + + // TODO(#8578): Replace finalizer with PhantomReference. + @SuppressWarnings("deprecation") + protected void finalize() throws Throwable { + super.finalize(); + + if (callbackHandle != 0) { + deleteCallback(callbackHandle); + callbackHandle = 0; + } + } } diff --git a/src/controller/java/src/chip/devicecontroller/GetConnectedDeviceCallbackJni.java b/src/controller/java/src/chip/devicecontroller/GetConnectedDeviceCallbackJni.java index 84338f8234..b45b04a778 100644 --- a/src/controller/java/src/chip/devicecontroller/GetConnectedDeviceCallbackJni.java +++ b/src/controller/java/src/chip/devicecontroller/GetConnectedDeviceCallbackJni.java @@ -17,29 +17,14 @@ */ package chip.devicecontroller; -import java.lang.ref.Cleaner; - /** JNI wrapper callback class for getting a connected device. */ public class GetConnectedDeviceCallbackJni { private final GetConnectedDeviceCallback wrappedCallback; private long callbackHandle; - private final Cleaner.Cleanable cleanable; - public GetConnectedDeviceCallbackJni(GetConnectedDeviceCallback wrappedCallback) { this.wrappedCallback = wrappedCallback; this.callbackHandle = newCallback(wrappedCallback); - - this.cleanable = - Cleaner.create() - .register( - this, - () -> { - if (callbackHandle != 0) { - deleteCallback(callbackHandle); - callbackHandle = 0; - } - }); } long getCallbackHandle() { @@ -50,6 +35,17 @@ long getCallbackHandle() { private native void deleteCallback(long callbackHandle); + // TODO(#8578): Replace finalizer with PhantomReference. + @SuppressWarnings("deprecation") + protected void finalize() throws Throwable { + super.finalize(); + + if (callbackHandle != 0) { + deleteCallback(callbackHandle); + callbackHandle = 0; + } + } + /** Callbacks for getting a device connected with PASE or CASE, depending on the context. */ public interface GetConnectedDeviceCallback { void onDeviceConnected(long devicePointer); diff --git a/src/controller/java/src/chip/devicecontroller/InvokeCallbackJni.java b/src/controller/java/src/chip/devicecontroller/InvokeCallbackJni.java index 69881a7784..ceb35eccef 100644 --- a/src/controller/java/src/chip/devicecontroller/InvokeCallbackJni.java +++ b/src/controller/java/src/chip/devicecontroller/InvokeCallbackJni.java @@ -18,29 +18,15 @@ package chip.devicecontroller; import chip.devicecontroller.model.InvokeElement; -import java.lang.ref.Cleaner; /** JNI wrapper callback class for {@link InvokeCallback}. */ public final class InvokeCallbackJni { private final InvokeCallback wrappedInvokeCallback; private long callbackHandle; - private final Cleaner.Cleanable cleanable; - public InvokeCallbackJni(InvokeCallback wrappedInvokeCallback) { this.wrappedInvokeCallback = wrappedInvokeCallback; this.callbackHandle = newCallback(); - - this.cleanable = - Cleaner.create() - .register( - this, - () -> { - if (callbackHandle != 0) { - deleteCallback(callbackHandle); - callbackHandle = 0; - } - }); } long getCallbackHandle() { @@ -69,4 +55,15 @@ private void onResponse( private void onDone() { wrappedInvokeCallback.onDone(); } + + // TODO(#8578): Replace finalizer with PhantomReference. + @SuppressWarnings("deprecation") + protected void finalize() throws Throwable { + super.finalize(); + + if (callbackHandle != 0) { + deleteCallback(callbackHandle); + callbackHandle = 0; + } + } } diff --git a/src/controller/java/src/chip/devicecontroller/ReportCallbackJni.java b/src/controller/java/src/chip/devicecontroller/ReportCallbackJni.java index 9ff86d1e9f..4f2529fa8d 100644 --- a/src/controller/java/src/chip/devicecontroller/ReportCallbackJni.java +++ b/src/controller/java/src/chip/devicecontroller/ReportCallbackJni.java @@ -20,7 +20,6 @@ import chip.devicecontroller.model.ChipAttributePath; import chip.devicecontroller.model.ChipEventPath; import chip.devicecontroller.model.NodeState; -import java.lang.ref.Cleaner; import javax.annotation.Nullable; /** JNI wrapper callback class for {@link ReportCallback}. */ @@ -31,8 +30,6 @@ public class ReportCallbackJni { private long callbackHandle; @Nullable private NodeState nodeState; - private final Cleaner.Cleanable cleanable; - public ReportCallbackJni( @Nullable SubscriptionEstablishedCallback subscriptionEstablishedCallback, ReportCallback reportCallback, @@ -42,17 +39,6 @@ public ReportCallbackJni( this.wrappedResubscriptionAttemptCallback = resubscriptionAttemptCallback; this.callbackHandle = newCallback(subscriptionEstablishedCallback, resubscriptionAttemptCallback); - - this.cleanable = - Cleaner.create() - .register( - this, - () -> { - if (callbackHandle != 0) { - deleteCallback(callbackHandle); - callbackHandle = 0; - } - }); } long getCallbackHandle() { @@ -102,4 +88,15 @@ private void onError( private void onDone() { wrappedReportCallback.onDone(); } + + // TODO(#8578): Replace finalizer with PhantomReference. + @SuppressWarnings("deprecation") + protected void finalize() throws Throwable { + super.finalize(); + + if (callbackHandle != 0) { + deleteCallback(callbackHandle); + callbackHandle = 0; + } + } } diff --git a/src/controller/java/src/chip/devicecontroller/WriteAttributesCallbackJni.java b/src/controller/java/src/chip/devicecontroller/WriteAttributesCallbackJni.java index 84a74c4d9e..7b95b30759 100644 --- a/src/controller/java/src/chip/devicecontroller/WriteAttributesCallbackJni.java +++ b/src/controller/java/src/chip/devicecontroller/WriteAttributesCallbackJni.java @@ -19,7 +19,6 @@ import chip.devicecontroller.model.ChipAttributePath; import chip.devicecontroller.model.Status; -import java.lang.ref.Cleaner; import javax.annotation.Nullable; /** JNI wrapper callback class for {@link WriteAttributesCallback}. */ @@ -27,22 +26,9 @@ public final class WriteAttributesCallbackJni { private final WriteAttributesCallback wrappedWriteAttributesCallback; private long callbackHandle; - private final Cleaner.Cleanable cleanable; - public WriteAttributesCallbackJni(WriteAttributesCallback wrappedWriteAttributesCallback) { this.wrappedWriteAttributesCallback = wrappedWriteAttributesCallback; this.callbackHandle = newCallback(); - - this.cleanable = - Cleaner.create() - .register( - this, - () -> { - if (callbackHandle != 0) { - deleteCallback(callbackHandle); - callbackHandle = 0; - } - }); } long getCallbackHandle() { @@ -75,4 +61,15 @@ private void onResponse( private void onDone() { wrappedWriteAttributesCallback.onDone(); } + + // TODO(#8578): Replace finalizer with PhantomReference. + @SuppressWarnings("deprecation") + protected void finalize() throws Throwable { + super.finalize(); + + if (callbackHandle != 0) { + deleteCallback(callbackHandle); + callbackHandle = 0; + } + } } From ee6341ea6a25a0aff45e1fe0b8370639e20c45d6 Mon Sep 17 00:00:00 2001 From: Shreyas Balakrishna Bhandare Date: Thu, 6 Feb 2025 23:31:47 -0800 Subject: [PATCH 19/39] Update chef air quality sample to use ug/m^3 (#37441) * Change pm10 unit from ppm to micrograms per cubic meters * Fix bug - micro is U not M --- examples/chef/common/chef-concentration-measurement.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/chef/common/chef-concentration-measurement.cpp b/examples/chef/common/chef-concentration-measurement.cpp index a23e66561d..f0db3395cf 100644 --- a/examples/chef/common/chef-concentration-measurement.cpp +++ b/examples/chef/common/chef-concentration-measurement.cpp @@ -306,7 +306,7 @@ void emberAfPm1ConcentrationMeasurementClusterInitCallback(EndpointId endpoint) void emberAfPm10ConcentrationMeasurementClusterInitCallback(EndpointId endpoint) { gPm10ConcentrationMeasurementInstance[EndpointId(endpoint)] = new Instance( - EndpointId(endpoint), Pm10ConcentrationMeasurement::Id, MeasurementMediumEnum::kAir, MeasurementUnitEnum::kPpm); + EndpointId(endpoint), Pm10ConcentrationMeasurement::Id, MeasurementMediumEnum::kAir, MeasurementUnitEnum::kUgm3); gPm10ConcentrationMeasurementInstance[EndpointId(endpoint)]->Init(); gPm10ConcentrationMeasurementInstance[EndpointId(endpoint)]->SetMeasuredValue(MakeNullable(50.0f)); gPm10ConcentrationMeasurementInstance[EndpointId(endpoint)]->SetMinMeasuredValue(MakeNullable(1.0f)); From 1348a8a3201df39f37670a55cea1bcd1aa8377c1 Mon Sep 17 00:00:00 2001 From: Jeff Tung <100387939+jtung-apple@users.noreply.github.com> Date: Thu, 6 Feb 2025 23:35:29 -0800 Subject: [PATCH 20/39] [Darwin] MTRDevice should throttle deviceBecameActive callbacks (#37436) * [Darwin] MTRDevice should throttle deviceBecameActive callbacks * * Use a slightly shorter interval with its own define for deviceBecameActive throttling. * Log when we start throttling deviceBecameActive callbacks. --------- Co-authored-by: Boris Zbarsky --- .../Framework/CHIP/MTRDevice_Concrete.mm | 32 ++++++++++++++++--- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/src/darwin/Framework/CHIP/MTRDevice_Concrete.mm b/src/darwin/Framework/CHIP/MTRDevice_Concrete.mm index 2a9ef219ee..4e29b0e5e3 100644 --- a/src/darwin/Framework/CHIP/MTRDevice_Concrete.mm +++ b/src/darwin/Framework/CHIP/MTRDevice_Concrete.mm @@ -331,6 +331,9 @@ @interface MTRDevice_Concrete () @property (nonatomic) NSDate * estimatedStartTimeFromGeneralDiagnosticsUpTime; +@property (nonatomic) NSDate * lastDeviceBecameActiveCallbackTime; +@property (nonatomic) BOOL throttlingDeviceBecameActiveCallbacks; + /** * If currentReadClient is non-null, that means that we successfully * called SendAutoResubscribeRequest on the ReadClient and have not yet gotten @@ -470,6 +473,7 @@ - (instancetype)initWithNodeID:(NSNumber *)nodeID controller:(MTRDeviceControlle _persistedClusters = [NSMutableSet set]; _highestObservedEventNumber = nil; _matterCPPObjectsHolder = [[MTRDeviceMatterCPPObjectsHolder alloc] init]; + _throttlingDeviceBecameActiveCallbacks = NO; // If there is a data store, make sure we have an observer to monitor system clock changes, so // NSDate-based write coalescing could be reset and not get into a bad state. @@ -864,6 +868,7 @@ - (void)_setDSTOffsets:(NSArray // subscription intervals are in seconds #define MTR_DEVICE_SUBSCRIPTION_MAX_INTERVAL_MIN (10 * 60) // 10 minutes (for now) #define MTR_DEVICE_SUBSCRIPTION_MAX_INTERVAL_MAX (60 * 60) // 60 minutes +#define MTR_DEVICE_MIN_SECONDS_BETWEEN_DEVICE_BECAME_ACTIVE_CALLBACKS (1 * 60) // 1 minute (for now) - (BOOL)_subscriptionsAllowed { @@ -1634,12 +1639,29 @@ - (void)_handleUnsolicitedMessageFromPublisher [self _changeState:MTRDeviceStateReachable]; - [self _callDelegatesWithBlock:^(id delegate) { - if ([delegate respondsToSelector:@selector(deviceBecameActive:)]) { - [delegate deviceBecameActive:self]; + // Given the framework requests a minimum subscription keep alive time of devices, this callback is not expected to happen more often than that + BOOL shouldCallDelegate = NO; + if (self.lastDeviceBecameActiveCallbackTime) { + NSTimeInterval intervalSinceLastCallback = -[self.lastDeviceBecameActiveCallbackTime timeIntervalSinceNow]; + if (intervalSinceLastCallback > MTR_DEVICE_MIN_SECONDS_BETWEEN_DEVICE_BECAME_ACTIVE_CALLBACKS) { + shouldCallDelegate = YES; } - }]; - [self _notifyDelegateOfPrivateInternalPropertiesChanges]; + } else { + shouldCallDelegate = YES; + } + + if (shouldCallDelegate) { + [self _callDelegatesWithBlock:^(id delegate) { + if ([delegate respondsToSelector:@selector(deviceBecameActive:)]) { + [delegate deviceBecameActive:self]; + } + }]; + self.lastDeviceBecameActiveCallbackTime = [NSDate now]; + self.throttlingDeviceBecameActiveCallbacks = NO; + } else if (!self.throttlingDeviceBecameActiveCallbacks) { + MTR_LOG("%@ throttling deviceBecameActive callbacks because report came in too soon after %@", self, self.lastDeviceBecameActiveCallbackTime); + self.throttlingDeviceBecameActiveCallbacks = YES; + } // in case this is called during exponential back off of subscription // reestablishment, this starts the attempt right away From c02a0913d8bf6880eb77f9d35fda9a03a2c6210d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mi=C5=82osz=20Tomkiel?= Date: Fri, 7 Feb 2025 13:45:59 +0100 Subject: [PATCH 21/39] [Tizen] Add ifdef for version-dependent Thread API (#37430) * Add ifdef * Restyled by clang-format --------- Co-authored-by: Restyled.io --- src/platform/Tizen/ThreadStackManagerImpl.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/platform/Tizen/ThreadStackManagerImpl.cpp b/src/platform/Tizen/ThreadStackManagerImpl.cpp index 0ae0f8f84a..f69974521c 100644 --- a/src/platform/Tizen/ThreadStackManagerImpl.cpp +++ b/src/platform/Tizen/ThreadStackManagerImpl.cpp @@ -521,12 +521,15 @@ CHIP_ERROR ThreadStackManagerImpl::_GetThreadVersion(uint16_t & version) { VerifyOrReturnError(mIsInitialized, CHIP_ERROR_UNINITIALIZED); +#if defined(TIZEN_NETWORK_THREAD_VERSION) && TIZEN_NETWORK_THREAD_VERSION >= 0x000900 int threadErr = thread_get_version(mThreadInstance, &version); VerifyOrReturnError(threadErr == THREAD_ERROR_NONE, TizenToChipError(threadErr), ChipLogError(DeviceLayer, "FAIL: Get thread version: %s", get_error_message(threadErr))); - ChipLogProgress(DeviceLayer, "Thread version [%u]", version); return CHIP_NO_ERROR; +#else + return CHIP_ERROR_NOT_IMPLEMENTED; +#endif } CHIP_ERROR ThreadStackManagerImpl::_GetPollPeriod(uint32_t & buf) From f53be4f36646fde87cd4dd49551a002ecfb2a414 Mon Sep 17 00:00:00 2001 From: Adrian Gielniewski Date: Fri, 7 Feb 2025 15:05:03 +0100 Subject: [PATCH 22/39] [Docker Image] Add zstd to chip-build (#37450) When running workflow locally using `act`, `Save bootstrap cache` step takes significant amount of time. This is caused by missing `zstd`. Signed-off-by: Adrian Gielniewski --- integrations/docker/images/base/chip-build/Dockerfile | 1 + integrations/docker/images/base/chip-build/version | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/integrations/docker/images/base/chip-build/Dockerfile b/integrations/docker/images/base/chip-build/Dockerfile index 2a64ab7049..5c154f6e82 100644 --- a/integrations/docker/images/base/chip-build/Dockerfile +++ b/integrations/docker/images/base/chip-build/Dockerfile @@ -105,6 +105,7 @@ RUN set -x \ unzip \ wget \ zlib1g-dev \ + zstd \ && rm -rf /var/lib/apt/lists/ \ && git lfs install \ && : # last line diff --git a/integrations/docker/images/base/chip-build/version b/integrations/docker/images/base/chip-build/version index b0158daf67..d12b99744a 100644 --- a/integrations/docker/images/base/chip-build/version +++ b/integrations/docker/images/base/chip-build/version @@ -1 +1 @@ -109 : [Tizen] Fix race when storing cert credentials +110 : [Tizen] Add zstd to base image From ff5f8fd9b388337bf8b24d768bb78c752c256b02 Mon Sep 17 00:00:00 2001 From: yunhanw-google Date: Fri, 7 Feb 2025 06:06:29 -0800 Subject: [PATCH 23/39] [Android][Docker]upgrade android sdk from 8 to 11 with java 11 support (#37444) * upgrade android sd to android 11 with java 11 support * Update Dockerfile --------- Co-authored-by: Andrei Litvin --- .../docker/images/base/chip-build/version | 2 +- .../images/stage-2/chip-build-java/Dockerfile | 4 ++-- .../stage-3/chip-build-android/Dockerfile | 18 +++++++++--------- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/integrations/docker/images/base/chip-build/version b/integrations/docker/images/base/chip-build/version index d12b99744a..0ff86b56e7 100644 --- a/integrations/docker/images/base/chip-build/version +++ b/integrations/docker/images/base/chip-build/version @@ -1 +1 @@ -110 : [Tizen] Add zstd to base image +111 : [Android] Update android sdk and java version diff --git a/integrations/docker/images/stage-2/chip-build-java/Dockerfile b/integrations/docker/images/stage-2/chip-build-java/Dockerfile index a8f328153c..c5b54e4c43 100644 --- a/integrations/docker/images/stage-2/chip-build-java/Dockerfile +++ b/integrations/docker/images/stage-2/chip-build-java/Dockerfile @@ -6,7 +6,7 @@ LABEL org.opencontainers.image.source https://github.com/project-chip/connectedh RUN set -x \ && apt-get update \ && DEBIAN_FRONTEND=noninteractive apt-get install -fy \ - openjdk-17-jdk \ + openjdk-11-jdk \ && rm -rf /var/lib/apt/lists/ \ && : # last line @@ -20,4 +20,4 @@ RUN set -x \ && : # last line ENV PATH $PATH:/usr/lib/kotlinc/bin -ENV JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64 +ENV JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64 diff --git a/integrations/docker/images/stage-3/chip-build-android/Dockerfile b/integrations/docker/images/stage-3/chip-build-android/Dockerfile index 3f3d8d40f1..eb2360ccb9 100644 --- a/integrations/docker/images/stage-3/chip-build-android/Dockerfile +++ b/integrations/docker/images/stage-3/chip-build-android/Dockerfile @@ -16,26 +16,26 @@ RUN set -x \ # Download and install android SDK RUN set -x \ - && wget -O /tmp/android-26.zip https://dl.google.com/android/repository/platform-26_r02.zip \ + && wget -O /tmp/android-30.zip https://dl.google.com/android/repository/platform-30_r03.zip \ && mkdir -p /opt/android/sdk/platforms \ && cd /opt/android/sdk/platforms \ - && unzip /tmp/android-26.zip \ - && mv android-8.0.0 android-26 \ - && rm -f /tmp/android-26.zip \ + && unzip /tmp/android-30.zip \ + && mv android-11 android-30 \ + && rm -f /tmp/android-30.zip \ && chmod -R a+rX /opt/android/sdk \ - && test -d /opt/android/sdk/platforms/android-26 \ + && test -d /opt/android/sdk/platforms/android-30 \ && : # last line # Download and install android command line tool (for installing `sdkmanager`) -# We need create latest folder inide cmdline-tools, since latest android commandline tool looks for this latest folder +# We need create 10.0 folder inide cmdline-tools, since latest android commandline tool looks for this latest folder # when running sdkmanager --licenses RUN set -x \ - && wget -O /tmp/cmdline-tools.zip https://dl.google.com/android/repository/commandlinetools-linux-11076708_latest.zip \ + && wget -O /tmp/cmdline-tools.zip https://dl.google.com/android/repository/commandlinetools-linux-9862592_latest.zip \ && cd /opt/android/sdk \ && mkdir -p temp \ && unzip /tmp/cmdline-tools.zip -d temp \ - && mkdir -p cmdline-tools/latest \ - && cp -rf temp/cmdline-tools/* cmdline-tools/latest \ + && mkdir -p cmdline-tools/10.0 \ + && cp -rf temp/cmdline-tools/* cmdline-tools/10.0 \ && rm -rf temp \ && test -d /opt/android/sdk/cmdline-tools \ && : # last line From 8deebeb002d6ef36ab89a57ac3e0a3f6836c6dac Mon Sep 17 00:00:00 2001 From: Borys Nykytiuk <165832970+BorysNykytiuk@users.noreply.github.com> Date: Fri, 7 Feb 2025 16:25:22 +0200 Subject: [PATCH 24/39] telink: add instructions how to use USB logging (#37376) - modify lighting-app telink REDME.md file Signed-off-by: Borys Nykytiuk --- examples/lighting-app/telink/README.md | 27 ++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/examples/lighting-app/telink/README.md b/examples/lighting-app/telink/README.md index ba41630d9f..d940d55aaf 100644 --- a/examples/lighting-app/telink/README.md +++ b/examples/lighting-app/telink/README.md @@ -74,6 +74,33 @@ To get output from device, connect UART to following pins: Baud rate: 115200 bits/s +### Using USB COM Port Instead of UART + +Alternatively, the USB COM port can be used instead of UART for console output. + +1. Build the project with the following parameter: + + ```bash + $ west build -b -- -DTLNK_USB_DONGLE=y + ``` + +2. Connect the USB cable to your device. A new serial device should appear in + your system (e.g., `/dev/ttyACM0` on Linux or a COM port on Windows). +3. Use your preferred terminal application (like `minicom`, `screen`, or + `PuTTY`) to connect to the newly detected serial device. +4. In your source code, ensure the following header is included and the USB + device stack is initialized: + + ```c + #ifdef CONFIG_USB_DEVICE_STACK + #include + #endif /* CONFIG_USB_DEVICE_STACK */ + + #ifdef CONFIG_USB_DEVICE_STACK + usb_enable(NULL); + #endif /* CONFIG_USB_DEVICE_STACK */ + ``` + ### Buttons The following buttons are available on **tlsr9518adk80d** board: From b536bc122ad1c2b0d17c9a2dc95d703fb27ea1fc Mon Sep 17 00:00:00 2001 From: Thomas Lea Date: Fri, 7 Feb 2025 10:52:07 -0600 Subject: [PATCH 25/39] Remove stale comment from ARL example (#37321) ExampleAccessRestrictionProvider.h had a comment referring to an event from a development iteration that was incorrect. Co-authored-by: Andrei Litvin --- examples/platform/linux/ExampleAccessRestrictionProvider.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/platform/linux/ExampleAccessRestrictionProvider.h b/examples/platform/linux/ExampleAccessRestrictionProvider.h index 731a8ae584..645c71a5b4 100644 --- a/examples/platform/linux/ExampleAccessRestrictionProvider.h +++ b/examples/platform/linux/ExampleAccessRestrictionProvider.h @@ -39,7 +39,7 @@ class ExampleAccessRestrictionProvider : public AccessRestrictionProvider protected: CHIP_ERROR DoRequestFabricRestrictionReview(const FabricIndex fabricIndex, uint64_t token, const std::vector & arl) { - // this example simply removes all restrictions and will generate AccessRestrictionEntryChanged events + // this example simply removes all restrictions when a review command is received Access::GetAccessControl().GetAccessRestrictionProvider()->SetEntries(fabricIndex, std::vector{}); chip::app::Clusters::AccessControl::Events::FabricRestrictionReviewUpdate::Type event{ .token = token, From ab065d21aa66804b3efc7719e82c4ad1ec34be63 Mon Sep 17 00:00:00 2001 From: Jae Son <12516308+jaehs6sam@users.noreply.github.com> Date: Fri, 7 Feb 2025 11:13:54 -0600 Subject: [PATCH 26/39] Update TC_OCC_3_2.py to fix test step 4d failure. (#37197) * Update TC_OCC_3_2.py Fixed 4d test step failure by removing legacy attributes and streamlining attribute subscription test. * Update TC_OCC_3_2.py * Update TC_OCC_3_2.py * Update TC_OCC_3_2.py * Update TC_OCC_3_2.py * Update TC_OCC_3_2.py --- src/python_testing/TC_OCC_3_2.py | 28 ++++------------------------ 1 file changed, 4 insertions(+), 24 deletions(-) diff --git a/src/python_testing/TC_OCC_3_2.py b/src/python_testing/TC_OCC_3_2.py index 9f41bd69bb..1005163143 100644 --- a/src/python_testing/TC_OCC_3_2.py +++ b/src/python_testing/TC_OCC_3_2.py @@ -44,8 +44,8 @@ import time import chip.clusters as Clusters -from chip.testing.matter_testing import (AttributeValue, ClusterAttributeChangeAccumulator, MatterBaseTest, TestStep, - async_test_body, await_sequence_of_reports, default_matter_test_main) +from chip.testing.matter_testing import (ClusterAttributeChangeAccumulator, MatterBaseTest, TestStep, async_test_body, + await_sequence_of_reports, default_matter_test_main) from mobly import asserts @@ -177,30 +177,10 @@ async def test_TC_OCC_3_2(self): self.step("4c") await self.write_single_attribute(attributes.HoldTime(hold_time_max)) - hold_time_dut = await self.read_occ_attribute_expect_success(attribute=attributes.HoldTime) - asserts.assert_equal(hold_time_dut, hold_time_max, "HoldTime did not match written HoldTimeMax") self.step("4d") - has_no_legacy_features = ((not has_feature_pir) and (not has_feature_ultrasonic) and (not has_feature_contact)) - - expect_legacy_pir_timing = has_pir_timing_attrib and (has_feature_pir or has_no_legacy_features) - expect_legacy_us_timing = has_ultrasonic_timing_attrib and has_feature_ultrasonic - expect_legacy_phy_timing = has_contact_timing_attrib and has_feature_contact - - # Build list of expectations based on attributes present. - all_expected_final_values = [AttributeValue(endpoint_id, attribute=cluster.Attributes.HoldTime, value=hold_time_max)] - if expect_legacy_pir_timing: - all_expected_final_values.append(AttributeValue( - endpoint_id, attribute=cluster.Attributes.PIROccupiedToUnoccupiedDelay, value=hold_time_max)) - if expect_legacy_us_timing: - all_expected_final_values.append(AttributeValue( - endpoint_id, attribute=cluster.Attributes.UltrasonicOccupiedToUnoccupiedDelay, value=hold_time_max)) - if expect_legacy_phy_timing: - all_expected_final_values.append(AttributeValue( - endpoint_id, attribute=cluster.Attributes.PhysicalContactOccupiedToUnoccupiedDelay, value=hold_time_max)) - - # Wait for the reports to come. - attrib_listener.await_all_final_values_reported(all_expected_final_values, timeout_sec=post_prompt_settle_delay_seconds) + await_sequence_of_reports(report_queue=attrib_listener.attribute_queue, endpoint_id=endpoint_id, + attribute=cluster.Attributes.HoldTime, sequence=[hold_time_max], timeout_sec=post_prompt_settle_delay_seconds) if __name__ == "__main__": From b9593646bff81773b51f500f0edbef3fdac7e06d Mon Sep 17 00:00:00 2001 From: Adrian Gielniewski Date: Fri, 7 Feb 2025 18:21:40 +0100 Subject: [PATCH 27/39] Move OnboardingCodesUtil out of app/server (#37401) * Move OnboardingCodesUtil out of server * Move OnboardingCodesUtils to separate target. * Remove shell dependency on server. Signed-off-by: Adrian Gielniewski * [mw320] Remove shell dependency on app/server Use PlatformMgr directly. Signed-off-by: Adrian Gielniewski * [NXP][examples] Add missing dependency Signed-off-by: Adrian Gielniewski * [linux][examples] Add missing dependency Signed-off-by: Adrian Gielniewski * [Infineon][examples] Add missing dependency Signed-off-by: Adrian Gielniewski --------- Signed-off-by: Adrian Gielniewski --- .../air-purifier-app/ameba/main/chipinterface.cpp | 2 +- examples/air-purifier-app/cc32xx/main/AppTask.cpp | 2 +- .../air-quality-sensor-app/silabs/src/AppTask.cpp | 2 +- .../all-clusters-app/ameba/main/chipinterface.cpp | 2 +- examples/all-clusters-app/asr/src/AppTask.cpp | 2 +- examples/all-clusters-app/esp32/main/AppTask.cpp | 2 +- .../esp32/main/include/DeviceWithDisplay.h | 2 +- examples/all-clusters-app/esp32/main/main.cpp | 2 +- .../all-clusters-app/infineon/psoc6/src/AppTask.cpp | 2 +- examples/all-clusters-app/mbed/main/AppTask.cpp | 2 +- .../all-clusters-app/nrfconnect/main/AppTask.cpp | 2 +- examples/all-clusters-app/nxp/mw320/main.cpp | 2 +- examples/all-clusters-app/nxp/rt/rt1060/BUILD.gn | 5 ++++- examples/all-clusters-app/nxp/rt/rt1170/BUILD.gn | 5 ++++- examples/all-clusters-app/nxp/rt/rw61x/BUILD.gn | 1 + .../ameba/main/chipinterface.cpp | 2 +- .../all-clusters-minimal-app/asr/src/AppTask.cpp | 2 +- .../all-clusters-minimal-app/esp32/main/AppTask.cpp | 2 +- .../esp32/main/include/DeviceWithDisplay.h | 2 +- .../all-clusters-minimal-app/esp32/main/main.cpp | 2 +- .../infineon/psoc6/src/AppTask.cpp | 2 +- .../all-clusters-minimal-app/mbed/main/AppTask.cpp | 2 +- .../nrfconnect/main/AppTask.cpp | 2 +- examples/bridge-app/asr/src/AppTask.cpp | 2 +- .../bridge-app/asr/subdevice/SubDeviceManager.cpp | 2 +- .../bridge-app/asr/subdevice/SubDeviceManager.h | 2 +- .../bridge-app/asr/subdevice/subdevice_test.cpp | 2 +- examples/bridge-app/esp32/main/main.cpp | 2 +- examples/chef/ameba/main/chipinterface.cpp | 2 +- examples/chef/esp32/main/main.cpp | 2 +- examples/chef/nrfconnect/main.cpp | 2 +- examples/chef/silabs/src/AppTask.cpp | 2 +- examples/common/imgui_ui/windows/qrcode.cpp | 2 +- examples/common/pigweed/rpc_services/Device.h | 2 +- .../bouffalolab/common/AppTask.cpp | 2 +- .../contact-sensor-app/nxp/k32w0/main/AppTask.cpp | 3 +-- examples/contact-sensor-app/nxp/k32w1/BUILD.gn | 1 + examples/contact-sensor-app/nxp/mcxw71/BUILD.gn | 1 + examples/dishwasher-app/asr/src/AppTask.cpp | 2 +- examples/dishwasher-app/silabs/src/AppTask.cpp | 2 +- examples/energy-management-app/esp32/main/main.cpp | 2 +- .../energy-management-app/silabs/src/AppTask.cpp | 2 +- examples/laundry-washer-app/nxp/rt/rt1060/BUILD.gn | 5 ++++- examples/laundry-washer-app/nxp/rt/rt1170/BUILD.gn | 5 ++++- examples/laundry-washer-app/nxp/rt/rw61x/BUILD.gn | 1 + .../light-switch-app/ameba/main/chipinterface.cpp | 2 +- examples/light-switch-app/asr/src/AppTask.cpp | 2 +- .../light-switch-app/cc13x4_26x4/src/AppTask.cpp | 2 +- examples/light-switch-app/esp32/main/main.cpp | 2 +- examples/light-switch-app/genio/src/AppTask.cpp | 2 +- .../light-switch-app/nrfconnect/main/AppTask.cpp | 2 +- examples/light-switch-app/qpg/src/AppTask.cpp | 2 +- examples/light-switch-app/silabs/src/AppTask.cpp | 2 +- examples/lighting-app/ameba/main/chipinterface.cpp | 2 +- examples/lighting-app/asr/src/AppTask.cpp | 2 +- examples/lighting-app/beken/main/chipinterface.cpp | 2 +- .../lighting-app/bouffalolab/common/AppTask.cpp | 2 +- examples/lighting-app/cc13x4_26x4/src/AppTask.cpp | 2 +- .../lighting-app/esp32/main/DeviceWithDisplay.h | 2 +- examples/lighting-app/esp32/main/main.cpp | 2 +- examples/lighting-app/genio/src/AppTask.cpp | 2 +- .../lighting-app/infineon/psoc6/src/AppTask.cpp | 2 +- examples/lighting-app/mbed/main/AppTask.cpp | 2 +- examples/lighting-app/nrfconnect/main/AppTask.cpp | 2 +- examples/lighting-app/nxp/k32w0/main/AppTask.cpp | 3 +-- examples/lighting-app/nxp/k32w1/BUILD.gn | 1 + examples/lighting-app/nxp/mcxw71/BUILD.gn | 1 + examples/lighting-app/qpg/src/AppTask.cpp | 2 +- examples/lighting-app/silabs/src/AppTask.cpp | 2 +- .../lighting-app/stm32/src/STM32WB5/AppTask.cpp | 2 +- examples/lit-icd-app/nrfconnect/main/AppTask.cpp | 2 +- examples/lit-icd-app/silabs/src/AppTask.cpp | 2 +- examples/lock-app/asr/src/AppTask.cpp | 2 +- examples/lock-app/cc13x4_26x4/src/AppTask.cpp | 2 +- examples/lock-app/cc32xx/main/AppTask.cpp | 2 +- examples/lock-app/esp32/main/AppTask.cpp | 2 +- examples/lock-app/genio/src/AppTask.cpp | 2 +- examples/lock-app/infineon/psoc6/src/AppTask.cpp | 2 +- examples/lock-app/mbed/main/AppTask.cpp | 2 +- examples/lock-app/nrfconnect/main/AppTask.cpp | 2 +- examples/lock-app/nxp/k32w/k32w0/main/AppTask.cpp | 3 +-- examples/lock-app/nxp/k32w1/BUILD.gn | 1 + examples/lock-app/nxp/mcxw71/BUILD.gn | 1 + examples/lock-app/qpg/src/AppTask.cpp | 2 +- examples/lock-app/silabs/src/AppTask.cpp | 2 +- examples/ota-provider-app/esp32/main/main.cpp | 2 +- examples/ota-requestor-app/asr/src/AppTask.cpp | 2 +- examples/ota-requestor-app/esp32/main/main.cpp | 2 +- examples/ota-requestor-app/genio/src/AppTask.cpp | 2 +- examples/ota-requestor-app/mbed/main/AppTask.cpp | 2 +- examples/platform/asr/init_Matter.cpp | 2 +- examples/platform/asr/shell/matter_shell.cpp | 2 +- .../platform/bouffalolab/common/plat/platform.cpp | 2 +- .../platform/infineon/cyw30739/cyw30739_example.gni | 1 + .../platform/infineon/cyw30739/matter_config.cpp | 2 +- examples/platform/linux/AppMain.cpp | 2 +- examples/platform/linux/BUILD.gn | 1 + examples/platform/linux/CommissionerMain.cpp | 2 +- examples/platform/linux/Options.cpp | 2 +- .../nxp/common/app_task/source/AppTaskBase.cpp | 2 +- examples/platform/nxp/se05x/linux/AppMain.cpp | 2 +- examples/platform/nxp/se05x/linux/BUILD.gn | 2 ++ .../platform/openiotsdk/app/openiotsdk_platform.cpp | 2 +- examples/platform/silabs/BaseApplication.cpp | 2 +- .../platform/telink/common/src/AppTaskCommon.cpp | 2 +- examples/pump-app/cc13x4_26x4/main/AppTask.cpp | 2 +- examples/pump-app/nrfconnect/main/AppTask.cpp | 2 +- examples/pump-app/silabs/src/AppTask.cpp | 2 +- .../cc13x4_26x4/main/AppTask.cpp | 2 +- .../pump-controller-app/nrfconnect/main/AppTask.cpp | 2 +- examples/refrigerator-app/asr/src/AppTask.cpp | 2 +- examples/refrigerator-app/silabs/src/AppTask.cpp | 2 +- examples/shell/cc13x4_26x4/main/AppTask.cpp | 3 +-- examples/smoke-co-alarm-app/silabs/src/AppTask.cpp | 2 +- .../temperature-measurement-app/asr/src/AppTask.cpp | 2 +- examples/thermostat/asr/src/AppTask.cpp | 2 +- examples/thermostat/genio/src/AppTask.cpp | 2 +- examples/thermostat/nxp/rt/rt1060/BUILD.gn | 5 ++++- examples/thermostat/nxp/rt/rt1170/BUILD.gn | 5 ++++- examples/thermostat/nxp/rt/rw61x/BUILD.gn | 1 + examples/thermostat/qpg/src/AppTask.cpp | 2 +- examples/thermostat/silabs/src/AppTask.cpp | 2 +- examples/thread-br-app/esp32/main/main.cpp | 2 +- examples/window-app/nrfconnect/main/AppTask.cpp | 2 +- examples/window-app/silabs/src/AppTask.cpp | 2 +- examples/window-app/silabs/src/WindowManager.cpp | 2 +- src/app/chip_data_model.cmake | 1 - src/app/server/BUILD.gn | 3 --- src/app/server/java/AndroidAppServerWrapper.cpp | 2 +- src/controller/python/chip/server/ServerInit.cpp | 2 +- src/lib/BUILD.gn | 1 + src/lib/shell/MainLoopMW320.cpp | 3 +-- src/lib/shell/commands/BUILD.gn | 2 +- src/lib/shell/commands/NFC.cpp | 2 +- src/lib/shell/commands/OnboardingCodes.cpp | 2 +- src/setup_payload/BUILD.gn | 13 +++++++++++++ .../OnboardingCodesUtil.cpp | 2 +- .../server => setup_payload}/OnboardingCodesUtil.h | 0 138 files changed, 166 insertions(+), 130 deletions(-) mode change 100755 => 100644 examples/bridge-app/asr/src/AppTask.cpp mode change 100755 => 100644 examples/light-switch-app/asr/src/AppTask.cpp mode change 100755 => 100644 examples/lighting-app/asr/src/AppTask.cpp mode change 100755 => 100644 examples/ota-requestor-app/asr/src/AppTask.cpp mode change 100755 => 100644 examples/temperature-measurement-app/asr/src/AppTask.cpp mode change 100755 => 100644 examples/thermostat/asr/src/AppTask.cpp rename src/{app/server => setup_payload}/OnboardingCodesUtil.cpp (99%) rename src/{app/server => setup_payload}/OnboardingCodesUtil.h (100%) diff --git a/examples/air-purifier-app/ameba/main/chipinterface.cpp b/examples/air-purifier-app/ameba/main/chipinterface.cpp index 766197dec3..e44d8ee8a2 100644 --- a/examples/air-purifier-app/ameba/main/chipinterface.cpp +++ b/examples/air-purifier-app/ameba/main/chipinterface.cpp @@ -30,7 +30,6 @@ #include #include #include -#include #include #include #include @@ -38,6 +37,7 @@ #include #include #include +#include #include #if CONFIG_ENABLE_AMEBA_CRYPTO #include diff --git a/examples/air-purifier-app/cc32xx/main/AppTask.cpp b/examples/air-purifier-app/cc32xx/main/AppTask.cpp index b604271d5f..a65387b957 100644 --- a/examples/air-purifier-app/cc32xx/main/AppTask.cpp +++ b/examples/air-purifier-app/cc32xx/main/AppTask.cpp @@ -39,8 +39,8 @@ #include #include -#include #include +#include #include #include diff --git a/examples/air-quality-sensor-app/silabs/src/AppTask.cpp b/examples/air-quality-sensor-app/silabs/src/AppTask.cpp index 572ec66dd5..facbcf3de5 100644 --- a/examples/air-quality-sensor-app/silabs/src/AppTask.cpp +++ b/examples/air-quality-sensor-app/silabs/src/AppTask.cpp @@ -39,13 +39,13 @@ #include #include #include -#include #include #include #include #include #include #include +#include #include #include diff --git a/examples/all-clusters-app/ameba/main/chipinterface.cpp b/examples/all-clusters-app/ameba/main/chipinterface.cpp index 80a98b9c3d..c4fbe01505 100644 --- a/examples/all-clusters-app/ameba/main/chipinterface.cpp +++ b/examples/all-clusters-app/ameba/main/chipinterface.cpp @@ -31,11 +31,11 @@ #include #include -#include #include #include #include #include +#include #include #include diff --git a/examples/all-clusters-app/asr/src/AppTask.cpp b/examples/all-clusters-app/asr/src/AppTask.cpp index ef3c86d272..bf9b5b3629 100644 --- a/examples/all-clusters-app/asr/src/AppTask.cpp +++ b/examples/all-clusters-app/asr/src/AppTask.cpp @@ -31,7 +31,6 @@ #include #include #include -#include #include #include #include @@ -40,6 +39,7 @@ #include #include #include +#include #include #include #include diff --git a/examples/all-clusters-app/esp32/main/AppTask.cpp b/examples/all-clusters-app/esp32/main/AppTask.cpp index 2b7e7d89b9..1ead5ed7be 100644 --- a/examples/all-clusters-app/esp32/main/AppTask.cpp +++ b/examples/all-clusters-app/esp32/main/AppTask.cpp @@ -28,7 +28,7 @@ #include "esp_idf_version.h" #include "esp_log.h" #include "freertos/FreeRTOS.h" -#include +#include #if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0) #include "esp_spi_flash.h" diff --git a/examples/all-clusters-app/esp32/main/include/DeviceWithDisplay.h b/examples/all-clusters-app/esp32/main/include/DeviceWithDisplay.h index 916d1c4449..3d28c6c381 100644 --- a/examples/all-clusters-app/esp32/main/include/DeviceWithDisplay.h +++ b/examples/all-clusters-app/esp32/main/include/DeviceWithDisplay.h @@ -33,8 +33,8 @@ #include #include -#include #include +#include #if CONFIG_HAVE_DISPLAY #include "Display.h" diff --git a/examples/all-clusters-app/esp32/main/main.cpp b/examples/all-clusters-app/esp32/main/main.cpp index 7ef84346e6..7c96990865 100644 --- a/examples/all-clusters-app/esp32/main/main.cpp +++ b/examples/all-clusters-app/esp32/main/main.cpp @@ -33,7 +33,6 @@ #include "nvs_flash.h" #include "platform/PlatformManager.h" #include "shell_extension/launch.h" -#include #include #include #include @@ -42,6 +41,7 @@ #include #include #include +#include #include #include diff --git a/examples/all-clusters-app/infineon/psoc6/src/AppTask.cpp b/examples/all-clusters-app/infineon/psoc6/src/AppTask.cpp index 5c416f847d..f763b5442c 100644 --- a/examples/all-clusters-app/infineon/psoc6/src/AppTask.cpp +++ b/examples/all-clusters-app/infineon/psoc6/src/AppTask.cpp @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include @@ -36,6 +35,7 @@ #include #include #include +#include #include #include diff --git a/examples/all-clusters-app/mbed/main/AppTask.cpp b/examples/all-clusters-app/mbed/main/AppTask.cpp index 3a6686b517..7228a77cf3 100644 --- a/examples/all-clusters-app/mbed/main/AppTask.cpp +++ b/examples/all-clusters-app/mbed/main/AppTask.cpp @@ -19,7 +19,7 @@ #include "AppTask.h" #include "LEDWidget.h" #include -#include +#include #include #include diff --git a/examples/all-clusters-app/nrfconnect/main/AppTask.cpp b/examples/all-clusters-app/nrfconnect/main/AppTask.cpp index f0f096ffcc..8ac7e36f47 100644 --- a/examples/all-clusters-app/nrfconnect/main/AppTask.cpp +++ b/examples/all-clusters-app/nrfconnect/main/AppTask.cpp @@ -24,8 +24,8 @@ #include -#include #include +#include #include #include diff --git a/examples/all-clusters-app/nxp/mw320/main.cpp b/examples/all-clusters-app/nxp/mw320/main.cpp index a828706b0f..fb032b950d 100644 --- a/examples/all-clusters-app/nxp/mw320/main.cpp +++ b/examples/all-clusters-app/nxp/mw320/main.cpp @@ -19,8 +19,8 @@ #include -#include #include +#include #include #include diff --git a/examples/all-clusters-app/nxp/rt/rt1060/BUILD.gn b/examples/all-clusters-app/nxp/rt/rt1060/BUILD.gn index d5a4936a48..d6cafd66ef 100644 --- a/examples/all-clusters-app/nxp/rt/rt1060/BUILD.gn +++ b/examples/all-clusters-app/nxp/rt/rt1060/BUILD.gn @@ -159,7 +159,10 @@ rt_executable("all_cluster_app") { "${common_example_dir}/matter_button/source/ButtonRegistrationDefault.cpp", ] - deps = [ "${chip_root}/examples/${app_common_folder}" ] + deps = [ + "${chip_root}/examples/${app_common_folder}", + "${chip_root}/src/setup_payload:onboarding-codes-utils", + ] sources += [ "${chip_root}/examples/${app_common_folder}/src/bridged-actions-stub.cpp", diff --git a/examples/all-clusters-app/nxp/rt/rt1170/BUILD.gn b/examples/all-clusters-app/nxp/rt/rt1170/BUILD.gn index edbd208506..c913b0541b 100644 --- a/examples/all-clusters-app/nxp/rt/rt1170/BUILD.gn +++ b/examples/all-clusters-app/nxp/rt/rt1170/BUILD.gn @@ -145,7 +145,10 @@ rt_executable("all_cluster_app") { "${common_example_dir}/matter_button/source/ButtonRegistrationEmpty.cpp", ] - deps = [ "${chip_root}/examples/${app_common_folder}" ] + deps = [ + "${chip_root}/examples/${app_common_folder}", + "${chip_root}/src/setup_payload:onboarding-codes-utils", + ] sources += [ "${chip_root}/examples/${app_common_folder}/src/bridged-actions-stub.cpp", diff --git a/examples/all-clusters-app/nxp/rt/rw61x/BUILD.gn b/examples/all-clusters-app/nxp/rt/rw61x/BUILD.gn index cb4e017b9b..af376d0f4a 100644 --- a/examples/all-clusters-app/nxp/rt/rw61x/BUILD.gn +++ b/examples/all-clusters-app/nxp/rt/rw61x/BUILD.gn @@ -167,6 +167,7 @@ rt_executable("all_cluster_app") { deps = [ "${chip_root}/examples/${app_common_folder}", "${chip_root}/src/platform/logging:default", + "${chip_root}/src/setup_payload:onboarding-codes-utils", ] sources += [ diff --git a/examples/all-clusters-minimal-app/ameba/main/chipinterface.cpp b/examples/all-clusters-minimal-app/ameba/main/chipinterface.cpp index 8f18742ca5..f3c09292c7 100644 --- a/examples/all-clusters-minimal-app/ameba/main/chipinterface.cpp +++ b/examples/all-clusters-minimal-app/ameba/main/chipinterface.cpp @@ -27,7 +27,6 @@ #include #include -#include #include #include #include @@ -38,6 +37,7 @@ #include #include #include +#include #include #include #include diff --git a/examples/all-clusters-minimal-app/asr/src/AppTask.cpp b/examples/all-clusters-minimal-app/asr/src/AppTask.cpp index 7e33211b8a..b9cf8ca47e 100644 --- a/examples/all-clusters-minimal-app/asr/src/AppTask.cpp +++ b/examples/all-clusters-minimal-app/asr/src/AppTask.cpp @@ -31,7 +31,6 @@ #include #include #include -#include #include #include #include @@ -40,6 +39,7 @@ #include #include #include +#include #include #include #include diff --git a/examples/all-clusters-minimal-app/esp32/main/AppTask.cpp b/examples/all-clusters-minimal-app/esp32/main/AppTask.cpp index 89394e65c2..8f75430a06 100644 --- a/examples/all-clusters-minimal-app/esp32/main/AppTask.cpp +++ b/examples/all-clusters-minimal-app/esp32/main/AppTask.cpp @@ -28,7 +28,7 @@ #include "esp_idf_version.h" #include "esp_log.h" #include "freertos/FreeRTOS.h" -#include +#include #if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0) #include "esp_spi_flash.h" diff --git a/examples/all-clusters-minimal-app/esp32/main/include/DeviceWithDisplay.h b/examples/all-clusters-minimal-app/esp32/main/include/DeviceWithDisplay.h index b9f89e15ee..b5340b26ae 100644 --- a/examples/all-clusters-minimal-app/esp32/main/include/DeviceWithDisplay.h +++ b/examples/all-clusters-minimal-app/esp32/main/include/DeviceWithDisplay.h @@ -39,8 +39,8 @@ #include #include #include -#include #include +#include #if CONFIG_DEVICE_TYPE_M5STACK #define BUTTON_1_GPIO_NUM ((gpio_num_t) 39) // Left button on M5Stack diff --git a/examples/all-clusters-minimal-app/esp32/main/main.cpp b/examples/all-clusters-minimal-app/esp32/main/main.cpp index 6066b21032..cdf645c71f 100644 --- a/examples/all-clusters-minimal-app/esp32/main/main.cpp +++ b/examples/all-clusters-minimal-app/esp32/main/main.cpp @@ -35,7 +35,6 @@ #include "shell_extension/launch.h" #include -#include #include #include #include @@ -43,6 +42,7 @@ #include #include #include +#include #include #if CONFIG_HAVE_DISPLAY diff --git a/examples/all-clusters-minimal-app/infineon/psoc6/src/AppTask.cpp b/examples/all-clusters-minimal-app/infineon/psoc6/src/AppTask.cpp index 1c0008b63b..f1f774a0e0 100644 --- a/examples/all-clusters-minimal-app/infineon/psoc6/src/AppTask.cpp +++ b/examples/all-clusters-minimal-app/infineon/psoc6/src/AppTask.cpp @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include @@ -36,6 +35,7 @@ #include #include #include +#include #include #include diff --git a/examples/all-clusters-minimal-app/mbed/main/AppTask.cpp b/examples/all-clusters-minimal-app/mbed/main/AppTask.cpp index 81f5f15a59..d5c37693be 100644 --- a/examples/all-clusters-minimal-app/mbed/main/AppTask.cpp +++ b/examples/all-clusters-minimal-app/mbed/main/AppTask.cpp @@ -21,11 +21,11 @@ #include #include -#include #include #include #include #include +#include #include #include diff --git a/examples/all-clusters-minimal-app/nrfconnect/main/AppTask.cpp b/examples/all-clusters-minimal-app/nrfconnect/main/AppTask.cpp index 64331a3200..90b8b2ed45 100644 --- a/examples/all-clusters-minimal-app/nrfconnect/main/AppTask.cpp +++ b/examples/all-clusters-minimal-app/nrfconnect/main/AppTask.cpp @@ -22,9 +22,9 @@ #include "LEDUtil.h" #include "binding-handler.h" -#include #include #include +#include #include #include diff --git a/examples/bridge-app/asr/src/AppTask.cpp b/examples/bridge-app/asr/src/AppTask.cpp old mode 100755 new mode 100644 index ea95500d40..e792deb629 --- a/examples/bridge-app/asr/src/AppTask.cpp +++ b/examples/bridge-app/asr/src/AppTask.cpp @@ -24,12 +24,12 @@ #include "init_Matter.h" #include "qrcodegen.h" #include -#include #include #include #include #include #include +#include #include #include diff --git a/examples/bridge-app/asr/subdevice/SubDeviceManager.cpp b/examples/bridge-app/asr/subdevice/SubDeviceManager.cpp index 776c4e4349..c0d45c0629 100644 --- a/examples/bridge-app/asr/subdevice/SubDeviceManager.cpp +++ b/examples/bridge-app/asr/subdevice/SubDeviceManager.cpp @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include @@ -35,6 +34,7 @@ #include #include #include +#include using namespace ::chip; using namespace ::chip::Credentials; diff --git a/examples/bridge-app/asr/subdevice/SubDeviceManager.h b/examples/bridge-app/asr/subdevice/SubDeviceManager.h index 29ce5067fe..deef8f7f80 100644 --- a/examples/bridge-app/asr/subdevice/SubDeviceManager.h +++ b/examples/bridge-app/asr/subdevice/SubDeviceManager.h @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include @@ -34,6 +33,7 @@ #include #include #include +#include using namespace ::chip; using namespace ::chip::Credentials; diff --git a/examples/bridge-app/asr/subdevice/subdevice_test.cpp b/examples/bridge-app/asr/subdevice/subdevice_test.cpp index ea2411d4ba..ad17525576 100644 --- a/examples/bridge-app/asr/subdevice/subdevice_test.cpp +++ b/examples/bridge-app/asr/subdevice/subdevice_test.cpp @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include @@ -34,6 +33,7 @@ #include #include #include +#include using namespace ::chip; using namespace ::chip::Credentials; diff --git a/examples/bridge-app/esp32/main/main.cpp b/examples/bridge-app/esp32/main/main.cpp index d1075385ce..2cc68ef559 100644 --- a/examples/bridge-app/esp32/main/main.cpp +++ b/examples/bridge-app/esp32/main/main.cpp @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include @@ -35,6 +34,7 @@ #include #include #include +#include #include #include diff --git a/examples/chef/ameba/main/chipinterface.cpp b/examples/chef/ameba/main/chipinterface.cpp index 52aed5ff4d..01acf92062 100644 --- a/examples/chef/ameba/main/chipinterface.cpp +++ b/examples/chef/ameba/main/chipinterface.cpp @@ -28,7 +28,6 @@ #include #include -#include #include #include #include @@ -40,6 +39,7 @@ #include #include #include +#include #include #include diff --git a/examples/chef/esp32/main/main.cpp b/examples/chef/esp32/main/main.cpp index 0abd996d41..1accdcdcae 100644 --- a/examples/chef/esp32/main/main.cpp +++ b/examples/chef/esp32/main/main.cpp @@ -30,9 +30,9 @@ #include #include -#include #include #include +#include #include #include diff --git a/examples/chef/nrfconnect/main.cpp b/examples/chef/nrfconnect/main.cpp index 14068cf37e..5ab73426d9 100644 --- a/examples/chef/nrfconnect/main.cpp +++ b/examples/chef/nrfconnect/main.cpp @@ -25,9 +25,9 @@ #include #include -#include #include #include +#include #include #include diff --git a/examples/chef/silabs/src/AppTask.cpp b/examples/chef/silabs/src/AppTask.cpp index aed343e1b3..c9066ea121 100644 --- a/examples/chef/silabs/src/AppTask.cpp +++ b/examples/chef/silabs/src/AppTask.cpp @@ -30,10 +30,10 @@ #endif // QR_CODE_ENABLED #endif // DISPLAY_ENABLED -#include #include #include #include +#include #include diff --git a/examples/common/imgui_ui/windows/qrcode.cpp b/examples/common/imgui_ui/windows/qrcode.cpp index 163110ed25..bdf08897a3 100644 --- a/examples/common/imgui_ui/windows/qrcode.cpp +++ b/examples/common/imgui_ui/windows/qrcode.cpp @@ -20,7 +20,7 @@ #include #include // examples/platform/linux/Options.h -#include +#include #include #include diff --git a/examples/common/pigweed/rpc_services/Device.h b/examples/common/pigweed/rpc_services/Device.h index 162cc6cd82..0b2f38bc5d 100644 --- a/examples/common/pigweed/rpc_services/Device.h +++ b/examples/common/pigweed/rpc_services/Device.h @@ -23,7 +23,6 @@ #include "app/clusters/ota-requestor/OTARequestorInterface.h" #include "app/server/CommissioningWindowManager.h" -#include "app/server/OnboardingCodesUtil.h" #include "app/server/Server.h" #include "credentials/FabricTable.h" #include "device_service/device_service.rpc.pb.h" @@ -31,6 +30,7 @@ #include "platform/ConfigurationManager.h" #include "platform/DiagnosticDataProvider.h" #include "platform/PlatformManager.h" +#include "setup_payload/OnboardingCodesUtil.h" #include #include #include diff --git a/examples/contact-sensor-app/bouffalolab/common/AppTask.cpp b/examples/contact-sensor-app/bouffalolab/common/AppTask.cpp index 5990e4201e..3acb94cd6a 100644 --- a/examples/contact-sensor-app/bouffalolab/common/AppTask.cpp +++ b/examples/contact-sensor-app/bouffalolab/common/AppTask.cpp @@ -19,11 +19,11 @@ #include #include -#include #include #include #include #include +#include #include #if HEAP_MONITORING diff --git a/examples/contact-sensor-app/nxp/k32w0/main/AppTask.cpp b/examples/contact-sensor-app/nxp/k32w0/main/AppTask.cpp index 9ac0c91815..ffeb434c6e 100644 --- a/examples/contact-sensor-app/nxp/k32w0/main/AppTask.cpp +++ b/examples/contact-sensor-app/nxp/k32w0/main/AppTask.cpp @@ -18,19 +18,18 @@ */ #include "AppTask.h" #include "AppEvent.h" -#include #include #include #include #include -#include #include #include #include #include #include #include +#include #include #include diff --git a/examples/contact-sensor-app/nxp/k32w1/BUILD.gn b/examples/contact-sensor-app/nxp/k32w1/BUILD.gn index e3694a5c44..8b32596478 100644 --- a/examples/contact-sensor-app/nxp/k32w1/BUILD.gn +++ b/examples/contact-sensor-app/nxp/k32w1/BUILD.gn @@ -218,6 +218,7 @@ mcxw71_k32w1_executable("contact_sensor_app") { deps += [ "${chip_root}/examples/providers:device_info_provider", "${chip_root}/src/platform/logging:default", + "${chip_root}/src/setup_payload:onboarding-codes-utils", ] #lit and sit are using different zap files diff --git a/examples/contact-sensor-app/nxp/mcxw71/BUILD.gn b/examples/contact-sensor-app/nxp/mcxw71/BUILD.gn index d0c6109ce4..df7e467ab7 100644 --- a/examples/contact-sensor-app/nxp/mcxw71/BUILD.gn +++ b/examples/contact-sensor-app/nxp/mcxw71/BUILD.gn @@ -217,6 +217,7 @@ mcxw71_k32w1_executable("contact_sensor_app") { deps += [ "${chip_root}/examples/providers:device_info_provider", "${chip_root}/src/platform/logging:default", + "${chip_root}/src/setup_payload:onboarding-codes-utils", ] #lit and sit are using different zap files diff --git a/examples/dishwasher-app/asr/src/AppTask.cpp b/examples/dishwasher-app/asr/src/AppTask.cpp index 8c038cfe36..aea885b3b2 100644 --- a/examples/dishwasher-app/asr/src/AppTask.cpp +++ b/examples/dishwasher-app/asr/src/AppTask.cpp @@ -21,11 +21,11 @@ #include "CHIPDeviceManager.h" #include "DeviceCallbacks.h" #include "qrcodegen.h" -#include #include #include #include #include +#include #include #include diff --git a/examples/dishwasher-app/silabs/src/AppTask.cpp b/examples/dishwasher-app/silabs/src/AppTask.cpp index 948f1b590b..de686f68e9 100644 --- a/examples/dishwasher-app/silabs/src/AppTask.cpp +++ b/examples/dishwasher-app/silabs/src/AppTask.cpp @@ -21,12 +21,12 @@ #include #include -#include #include #include #include #include #include +#include #include #include diff --git a/examples/energy-management-app/esp32/main/main.cpp b/examples/energy-management-app/esp32/main/main.cpp index e63c110d35..76d9b831ad 100644 --- a/examples/energy-management-app/esp32/main/main.cpp +++ b/examples/energy-management-app/esp32/main/main.cpp @@ -38,11 +38,11 @@ #include "shell_extension/openthread_cli_register.h" #include #include -#include #include #include #include #include +#include #if CONFIG_ENABLE_ESP32_FACTORY_DATA_PROVIDER #include diff --git a/examples/energy-management-app/silabs/src/AppTask.cpp b/examples/energy-management-app/silabs/src/AppTask.cpp index b5155f1dd3..c4f0c3be79 100644 --- a/examples/energy-management-app/silabs/src/AppTask.cpp +++ b/examples/energy-management-app/silabs/src/AppTask.cpp @@ -28,12 +28,12 @@ #include #include #include -#include #include #include #include #include #include +#include #include diff --git a/examples/laundry-washer-app/nxp/rt/rt1060/BUILD.gn b/examples/laundry-washer-app/nxp/rt/rt1060/BUILD.gn index 4e41741946..874f899e01 100644 --- a/examples/laundry-washer-app/nxp/rt/rt1060/BUILD.gn +++ b/examples/laundry-washer-app/nxp/rt/rt1060/BUILD.gn @@ -178,7 +178,10 @@ rt_executable("laundry-washer") { "${common_example_dir}/matter_button/source/ButtonRegistrationDefault.cpp", ] - deps = [ "${chip_root}/examples/${app_common_folder}" ] + deps = [ + "${chip_root}/examples/${app_common_folder}", + "${chip_root}/src/setup_payload:onboarding-codes-utils", + ] sources += [ "${chip_root}/examples/all-clusters-app/all-clusters-common/src/bridged-actions-stub.cpp", diff --git a/examples/laundry-washer-app/nxp/rt/rt1170/BUILD.gn b/examples/laundry-washer-app/nxp/rt/rt1170/BUILD.gn index 0e0e71e8c2..7b87f7497f 100644 --- a/examples/laundry-washer-app/nxp/rt/rt1170/BUILD.gn +++ b/examples/laundry-washer-app/nxp/rt/rt1170/BUILD.gn @@ -166,7 +166,10 @@ rt_executable("laundry-washer-app") { "${common_example_dir}/matter_button/source/ButtonRegistrationEmpty.cpp", ] - deps = [ "${chip_root}/examples/${app_common_folder}" ] + deps = [ + "${chip_root}/examples/${app_common_folder}", + "${chip_root}/src/setup_payload:onboarding-codes-utils", + ] sources += [ "${chip_root}/examples/all-clusters-app/all-clusters-common/src/bridged-actions-stub.cpp", diff --git a/examples/laundry-washer-app/nxp/rt/rw61x/BUILD.gn b/examples/laundry-washer-app/nxp/rt/rw61x/BUILD.gn index 1ef89a3852..a7dcee0a8d 100644 --- a/examples/laundry-washer-app/nxp/rt/rw61x/BUILD.gn +++ b/examples/laundry-washer-app/nxp/rt/rw61x/BUILD.gn @@ -188,6 +188,7 @@ rt_executable("laundry-washer") { deps = [ "${chip_root}/examples/${app_common_folder}", "${chip_root}/src/platform/logging:default", + "${chip_root}/src/setup_payload:onboarding-codes-utils", ] sources += [ diff --git a/examples/light-switch-app/ameba/main/chipinterface.cpp b/examples/light-switch-app/ameba/main/chipinterface.cpp index f883f0e030..0b51b49d54 100644 --- a/examples/light-switch-app/ameba/main/chipinterface.cpp +++ b/examples/light-switch-app/ameba/main/chipinterface.cpp @@ -29,13 +29,13 @@ #include #include -#include #include #include #include #include #include #include +#include #if CONFIG_ENABLE_AMEBA_CRYPTO #include #endif diff --git a/examples/light-switch-app/asr/src/AppTask.cpp b/examples/light-switch-app/asr/src/AppTask.cpp old mode 100755 new mode 100644 index 6dcabc80a9..f8b3bcb4da --- a/examples/light-switch-app/asr/src/AppTask.cpp +++ b/examples/light-switch-app/asr/src/AppTask.cpp @@ -30,7 +30,6 @@ #include #include #include -#include #include #include #include @@ -41,6 +40,7 @@ #include #include #include +#include #include #include diff --git a/examples/light-switch-app/cc13x4_26x4/src/AppTask.cpp b/examples/light-switch-app/cc13x4_26x4/src/AppTask.cpp index ce836b0c26..f562e8bbfe 100644 --- a/examples/light-switch-app/cc13x4_26x4/src/AppTask.cpp +++ b/examples/light-switch-app/cc13x4_26x4/src/AppTask.cpp @@ -50,9 +50,9 @@ #include #include #include -#include #include #include +#include #include #include diff --git a/examples/light-switch-app/esp32/main/main.cpp b/examples/light-switch-app/esp32/main/main.cpp index 88b34f2b9a..5072e5584a 100644 --- a/examples/light-switch-app/esp32/main/main.cpp +++ b/examples/light-switch-app/esp32/main/main.cpp @@ -31,10 +31,10 @@ #include "nvs_flash.h" #include "shell_extension/launch.h" -#include #include #include #include +#include #if CONFIG_ENABLE_ESP32_FACTORY_DATA_PROVIDER #include diff --git a/examples/light-switch-app/genio/src/AppTask.cpp b/examples/light-switch-app/genio/src/AppTask.cpp index 95adc2f402..bcb5f58ce1 100644 --- a/examples/light-switch-app/genio/src/AppTask.cpp +++ b/examples/light-switch-app/genio/src/AppTask.cpp @@ -27,10 +27,10 @@ #include #include -#include #include #include #include +#include #include diff --git a/examples/light-switch-app/nrfconnect/main/AppTask.cpp b/examples/light-switch-app/nrfconnect/main/AppTask.cpp index a7420e44c4..6eddd87840 100644 --- a/examples/light-switch-app/nrfconnect/main/AppTask.cpp +++ b/examples/light-switch-app/nrfconnect/main/AppTask.cpp @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include @@ -36,6 +35,7 @@ #include #include #include +#include #include #ifdef CONFIG_CHIP_WIFI diff --git a/examples/light-switch-app/qpg/src/AppTask.cpp b/examples/light-switch-app/qpg/src/AppTask.cpp index d9878c7fe3..959f2e63aa 100644 --- a/examples/light-switch-app/qpg/src/AppTask.cpp +++ b/examples/light-switch-app/qpg/src/AppTask.cpp @@ -29,7 +29,7 @@ using namespace ::chip; #include "AppTask.h" #include "ota.h" -#include +#include #include #include diff --git a/examples/light-switch-app/silabs/src/AppTask.cpp b/examples/light-switch-app/silabs/src/AppTask.cpp index 140a99136d..2ffaf11a73 100644 --- a/examples/light-switch-app/silabs/src/AppTask.cpp +++ b/examples/light-switch-app/silabs/src/AppTask.cpp @@ -33,13 +33,13 @@ #include "qrcodegen.h" #endif // QR_CODE_ENABLED #endif // DISPLAY_ENABLED -#include #include #include #include #include #include #include +#include #include #include diff --git a/examples/lighting-app/ameba/main/chipinterface.cpp b/examples/lighting-app/ameba/main/chipinterface.cpp index 0587d3134c..b336baddd2 100644 --- a/examples/lighting-app/ameba/main/chipinterface.cpp +++ b/examples/lighting-app/ameba/main/chipinterface.cpp @@ -31,12 +31,12 @@ #include #include -#include #include #include #include #include #include +#include #if CONFIG_ENABLE_AMEBA_CRYPTO #include #endif diff --git a/examples/lighting-app/asr/src/AppTask.cpp b/examples/lighting-app/asr/src/AppTask.cpp old mode 100755 new mode 100644 index 9bbd40af01..5684d5bc1f --- a/examples/lighting-app/asr/src/AppTask.cpp +++ b/examples/lighting-app/asr/src/AppTask.cpp @@ -23,11 +23,11 @@ #include "DeviceCallbacks.h" #include "LEDWidget.h" #include "qrcodegen.h" -#include #include #include #include #include +#include #include #include diff --git a/examples/lighting-app/beken/main/chipinterface.cpp b/examples/lighting-app/beken/main/chipinterface.cpp index 69111dea79..61d067bbe5 100644 --- a/examples/lighting-app/beken/main/chipinterface.cpp +++ b/examples/lighting-app/beken/main/chipinterface.cpp @@ -28,11 +28,11 @@ #include #include -#include #include #include #include #include +#include #include #include diff --git a/examples/lighting-app/bouffalolab/common/AppTask.cpp b/examples/lighting-app/bouffalolab/common/AppTask.cpp index aa2039bf4e..99fb0a4c07 100644 --- a/examples/lighting-app/bouffalolab/common/AppTask.cpp +++ b/examples/lighting-app/bouffalolab/common/AppTask.cpp @@ -20,12 +20,12 @@ #include #include -#include #include #include #include #include #include +#include #include #if HEAP_MONITORING diff --git a/examples/lighting-app/cc13x4_26x4/src/AppTask.cpp b/examples/lighting-app/cc13x4_26x4/src/AppTask.cpp index 3ff950ba0c..35982c5f5e 100644 --- a/examples/lighting-app/cc13x4_26x4/src/AppTask.cpp +++ b/examples/lighting-app/cc13x4_26x4/src/AppTask.cpp @@ -44,10 +44,10 @@ #include #include -#include #include #include #include +#include #include #include diff --git a/examples/lighting-app/esp32/main/DeviceWithDisplay.h b/examples/lighting-app/esp32/main/DeviceWithDisplay.h index a52a50f798..01c5b448b1 100644 --- a/examples/lighting-app/esp32/main/DeviceWithDisplay.h +++ b/examples/lighting-app/esp32/main/DeviceWithDisplay.h @@ -37,8 +37,8 @@ #include #include -#include #include +#include #if CONFIG_DEVICE_TYPE_M5STACK #define BUTTON_1_GPIO_NUM ((gpio_num_t) 39) // Left button on M5Stack diff --git a/examples/lighting-app/esp32/main/main.cpp b/examples/lighting-app/esp32/main/main.cpp index 9b2d6e1d3e..8604c6594c 100644 --- a/examples/lighting-app/esp32/main/main.cpp +++ b/examples/lighting-app/esp32/main/main.cpp @@ -34,10 +34,10 @@ #include "shell_extension/launch.h" #include "shell_extension/openthread_cli_register.h" #include -#include #include #include #include +#include #if CONFIG_ENABLE_ESP_INSIGHTS_SYSTEM_STATS #include diff --git a/examples/lighting-app/genio/src/AppTask.cpp b/examples/lighting-app/genio/src/AppTask.cpp index b6b31cec05..61c958c9ad 100644 --- a/examples/lighting-app/genio/src/AppTask.cpp +++ b/examples/lighting-app/genio/src/AppTask.cpp @@ -29,10 +29,10 @@ #include #include #include -#include #include #include #include +#include #include diff --git a/examples/lighting-app/infineon/psoc6/src/AppTask.cpp b/examples/lighting-app/infineon/psoc6/src/AppTask.cpp index 47d68bc3be..871a44fb63 100644 --- a/examples/lighting-app/infineon/psoc6/src/AppTask.cpp +++ b/examples/lighting-app/infineon/psoc6/src/AppTask.cpp @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include @@ -34,6 +33,7 @@ #include #include #include +#include #include #include diff --git a/examples/lighting-app/mbed/main/AppTask.cpp b/examples/lighting-app/mbed/main/AppTask.cpp index c4def4fe0e..b1fa44ba50 100644 --- a/examples/lighting-app/mbed/main/AppTask.cpp +++ b/examples/lighting-app/mbed/main/AppTask.cpp @@ -21,13 +21,13 @@ #include "LightingManager.h" #include -#include #include #include #include #include #include #include +#include // mbed-os headers #include "drivers/Timeout.h" diff --git a/examples/lighting-app/nrfconnect/main/AppTask.cpp b/examples/lighting-app/nrfconnect/main/AppTask.cpp index 93f5cf44c0..2e0834fe54 100644 --- a/examples/lighting-app/nrfconnect/main/AppTask.cpp +++ b/examples/lighting-app/nrfconnect/main/AppTask.cpp @@ -30,7 +30,6 @@ #include #include #include -#include #include #include #include @@ -40,6 +39,7 @@ #include #include #include +#include #include #ifdef CONFIG_CHIP_WIFI diff --git a/examples/lighting-app/nxp/k32w0/main/AppTask.cpp b/examples/lighting-app/nxp/k32w0/main/AppTask.cpp index 62221a23f1..78eea44ff5 100644 --- a/examples/lighting-app/nxp/k32w0/main/AppTask.cpp +++ b/examples/lighting-app/nxp/k32w0/main/AppTask.cpp @@ -18,11 +18,9 @@ */ #include "AppTask.h" #include "AppEvent.h" -#include #include #include -#include #include #include #include @@ -30,6 +28,7 @@ #include #include #include +#include #include #include diff --git a/examples/lighting-app/nxp/k32w1/BUILD.gn b/examples/lighting-app/nxp/k32w1/BUILD.gn index e66b9c3bf2..63a9106769 100644 --- a/examples/lighting-app/nxp/k32w1/BUILD.gn +++ b/examples/lighting-app/nxp/k32w1/BUILD.gn @@ -208,6 +208,7 @@ mcxw71_k32w1_executable("light_app") { deps += [ "${chip_root}/examples/providers:device_info_provider", "${chip_root}/src/platform/logging:default", + "${chip_root}/src/setup_payload:onboarding-codes-utils", ] if (nxp_config_dimmable_led) { diff --git a/examples/lighting-app/nxp/mcxw71/BUILD.gn b/examples/lighting-app/nxp/mcxw71/BUILD.gn index 815f95debd..82f516e9d8 100644 --- a/examples/lighting-app/nxp/mcxw71/BUILD.gn +++ b/examples/lighting-app/nxp/mcxw71/BUILD.gn @@ -211,6 +211,7 @@ mcxw71_k32w1_executable("light_app") { deps += [ "${chip_root}/examples/providers:device_info_provider", "${chip_root}/src/platform/logging:default", + "${chip_root}/src/setup_payload:onboarding-codes-utils", ] if (nxp_config_dimmable_led) { diff --git a/examples/lighting-app/qpg/src/AppTask.cpp b/examples/lighting-app/qpg/src/AppTask.cpp index 53b255dfa8..b74f02b599 100644 --- a/examples/lighting-app/qpg/src/AppTask.cpp +++ b/examples/lighting-app/qpg/src/AppTask.cpp @@ -35,11 +35,11 @@ #include #include #include -#include #include #include #include #include +#include #include #include diff --git a/examples/lighting-app/silabs/src/AppTask.cpp b/examples/lighting-app/silabs/src/AppTask.cpp index 4f74ca7f34..f3e624e988 100644 --- a/examples/lighting-app/silabs/src/AppTask.cpp +++ b/examples/lighting-app/silabs/src/AppTask.cpp @@ -24,9 +24,9 @@ #include "LEDWidget.h" #include -#include #include #include +#include #include diff --git a/examples/lighting-app/stm32/src/STM32WB5/AppTask.cpp b/examples/lighting-app/stm32/src/STM32WB5/AppTask.cpp index 701493b777..0ed3497d33 100644 --- a/examples/lighting-app/stm32/src/STM32WB5/AppTask.cpp +++ b/examples/lighting-app/stm32/src/STM32WB5/AppTask.cpp @@ -38,13 +38,13 @@ #include #include #include -#include #include #include #include #include #include #include +#include #include #include diff --git a/examples/lit-icd-app/nrfconnect/main/AppTask.cpp b/examples/lit-icd-app/nrfconnect/main/AppTask.cpp index 64000faa67..e4af08246c 100644 --- a/examples/lit-icd-app/nrfconnect/main/AppTask.cpp +++ b/examples/lit-icd-app/nrfconnect/main/AppTask.cpp @@ -23,8 +23,8 @@ #include -#include #include +#include #include #include diff --git a/examples/lit-icd-app/silabs/src/AppTask.cpp b/examples/lit-icd-app/silabs/src/AppTask.cpp index 0f330e700b..d7e97d0bb2 100644 --- a/examples/lit-icd-app/silabs/src/AppTask.cpp +++ b/examples/lit-icd-app/silabs/src/AppTask.cpp @@ -35,13 +35,13 @@ #include #include -#include #include #include #include #include #include #include +#include #include #include diff --git a/examples/lock-app/asr/src/AppTask.cpp b/examples/lock-app/asr/src/AppTask.cpp index 4d359a4bc6..ecb794286e 100644 --- a/examples/lock-app/asr/src/AppTask.cpp +++ b/examples/lock-app/asr/src/AppTask.cpp @@ -29,12 +29,12 @@ #include #include #include -#include #include #include #include #include #include +#include #include #include diff --git a/examples/lock-app/cc13x4_26x4/src/AppTask.cpp b/examples/lock-app/cc13x4_26x4/src/AppTask.cpp index b67d795e1b..98e4fc85e8 100644 --- a/examples/lock-app/cc13x4_26x4/src/AppTask.cpp +++ b/examples/lock-app/cc13x4_26x4/src/AppTask.cpp @@ -43,10 +43,10 @@ #include #include -#include #include #include #include +#include #include #include diff --git a/examples/lock-app/cc32xx/main/AppTask.cpp b/examples/lock-app/cc32xx/main/AppTask.cpp index 4973c7a380..8462e12e62 100644 --- a/examples/lock-app/cc32xx/main/AppTask.cpp +++ b/examples/lock-app/cc32xx/main/AppTask.cpp @@ -39,8 +39,8 @@ #include #include -#include #include +#include #include #include diff --git a/examples/lock-app/esp32/main/AppTask.cpp b/examples/lock-app/esp32/main/AppTask.cpp index fbca981316..84182fe46a 100644 --- a/examples/lock-app/esp32/main/AppTask.cpp +++ b/examples/lock-app/esp32/main/AppTask.cpp @@ -21,8 +21,8 @@ #include "esp_log.h" #include #include -#include #include +#include #include #include diff --git a/examples/lock-app/genio/src/AppTask.cpp b/examples/lock-app/genio/src/AppTask.cpp index f27a2fcad7..20806f989d 100644 --- a/examples/lock-app/genio/src/AppTask.cpp +++ b/examples/lock-app/genio/src/AppTask.cpp @@ -28,10 +28,10 @@ #include #include #include -#include #include #include #include +#include #include diff --git a/examples/lock-app/infineon/psoc6/src/AppTask.cpp b/examples/lock-app/infineon/psoc6/src/AppTask.cpp index c4880e1093..b5aaf64def 100644 --- a/examples/lock-app/infineon/psoc6/src/AppTask.cpp +++ b/examples/lock-app/infineon/psoc6/src/AppTask.cpp @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include @@ -36,6 +35,7 @@ #include #include #include +#include #include #include diff --git a/examples/lock-app/mbed/main/AppTask.cpp b/examples/lock-app/mbed/main/AppTask.cpp index 851d96a61b..94cc8e37f4 100644 --- a/examples/lock-app/mbed/main/AppTask.cpp +++ b/examples/lock-app/mbed/main/AppTask.cpp @@ -21,13 +21,13 @@ #include #include -#include #include #include #include #include #include #include +#include // mbed-os headers #include "drivers/Timeout.h" diff --git a/examples/lock-app/nrfconnect/main/AppTask.cpp b/examples/lock-app/nrfconnect/main/AppTask.cpp index 0706374bef..8248227d51 100644 --- a/examples/lock-app/nrfconnect/main/AppTask.cpp +++ b/examples/lock-app/nrfconnect/main/AppTask.cpp @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include @@ -37,6 +36,7 @@ #include #include #include +#include #include #ifdef CONFIG_CHIP_WIFI diff --git a/examples/lock-app/nxp/k32w/k32w0/main/AppTask.cpp b/examples/lock-app/nxp/k32w/k32w0/main/AppTask.cpp index cda08552ca..bdb4af8202 100644 --- a/examples/lock-app/nxp/k32w/k32w0/main/AppTask.cpp +++ b/examples/lock-app/nxp/k32w/k32w0/main/AppTask.cpp @@ -18,12 +18,10 @@ */ #include "AppTask.h" #include "AppEvent.h" -#include #include #include #include -#include #include #include #include @@ -31,6 +29,7 @@ #include #include #include +#include #include #include diff --git a/examples/lock-app/nxp/k32w1/BUILD.gn b/examples/lock-app/nxp/k32w1/BUILD.gn index ba1d9053ce..52e7835c3e 100644 --- a/examples/lock-app/nxp/k32w1/BUILD.gn +++ b/examples/lock-app/nxp/k32w1/BUILD.gn @@ -250,6 +250,7 @@ mcxw71_k32w1_executable("lock_app") { deps += [ "${chip_root}/examples/providers:device_info_provider", "${chip_root}/src/platform/logging:default", + "${chip_root}/src/setup_payload:onboarding-codes-utils", ] deps += [ "${chip_root}/examples/lock-app/nxp/zap:zap" ] diff --git a/examples/lock-app/nxp/mcxw71/BUILD.gn b/examples/lock-app/nxp/mcxw71/BUILD.gn index f49e938aa7..dacb4d83c2 100644 --- a/examples/lock-app/nxp/mcxw71/BUILD.gn +++ b/examples/lock-app/nxp/mcxw71/BUILD.gn @@ -250,6 +250,7 @@ mcxw71_k32w1_executable("lock_app") { deps += [ "${chip_root}/examples/providers:device_info_provider", "${chip_root}/src/platform/logging:default", + "${chip_root}/src/setup_payload:onboarding-codes-utils", ] deps += [ "${chip_root}/examples/lock-app/nxp/zap:zap" ] diff --git a/examples/lock-app/qpg/src/AppTask.cpp b/examples/lock-app/qpg/src/AppTask.cpp index 35d972aa7a..6b147e85b4 100644 --- a/examples/lock-app/qpg/src/AppTask.cpp +++ b/examples/lock-app/qpg/src/AppTask.cpp @@ -28,7 +28,7 @@ #include "AppTask.h" #include "ota.h" -#include +#include #include #include diff --git a/examples/lock-app/silabs/src/AppTask.cpp b/examples/lock-app/silabs/src/AppTask.cpp index 4e4d05a810..3dd0a0ba7c 100644 --- a/examples/lock-app/silabs/src/AppTask.cpp +++ b/examples/lock-app/silabs/src/AppTask.cpp @@ -37,9 +37,9 @@ #include #include -#include #include #include +#include #include diff --git a/examples/ota-provider-app/esp32/main/main.cpp b/examples/ota-provider-app/esp32/main/main.cpp index ae1a9906f2..16541a652f 100644 --- a/examples/ota-provider-app/esp32/main/main.cpp +++ b/examples/ota-provider-app/esp32/main/main.cpp @@ -20,7 +20,6 @@ #include "esp_spi_flash.h" #include "esp_spiffs.h" #include "nvs_flash.h" -#include #include #include #include @@ -28,6 +27,7 @@ #include #include #include +#include #include #include diff --git a/examples/ota-requestor-app/asr/src/AppTask.cpp b/examples/ota-requestor-app/asr/src/AppTask.cpp old mode 100755 new mode 100644 index 78c4ec47b8..152db9d898 --- a/examples/ota-requestor-app/asr/src/AppTask.cpp +++ b/examples/ota-requestor-app/asr/src/AppTask.cpp @@ -24,12 +24,12 @@ #include "init_Matter.h" #include "qrcodegen.h" #include -#include #include #include #include #include #include +#include #include #include diff --git a/examples/ota-requestor-app/esp32/main/main.cpp b/examples/ota-requestor-app/esp32/main/main.cpp index e375ded305..dd13cf924d 100644 --- a/examples/ota-requestor-app/esp32/main/main.cpp +++ b/examples/ota-requestor-app/esp32/main/main.cpp @@ -24,7 +24,6 @@ #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "nvs_flash.h" -#include #include #include #include @@ -32,6 +31,7 @@ #include #include #include +#include #include #include "OTAImageProcessorImpl.h" diff --git a/examples/ota-requestor-app/genio/src/AppTask.cpp b/examples/ota-requestor-app/genio/src/AppTask.cpp index 68826454a2..9da5ca25ba 100644 --- a/examples/ota-requestor-app/genio/src/AppTask.cpp +++ b/examples/ota-requestor-app/genio/src/AppTask.cpp @@ -18,11 +18,11 @@ */ #include #include -#include #include #include #include #include +#include #include diff --git a/examples/ota-requestor-app/mbed/main/AppTask.cpp b/examples/ota-requestor-app/mbed/main/AppTask.cpp index cad1b73b00..b08d7001a9 100644 --- a/examples/ota-requestor-app/mbed/main/AppTask.cpp +++ b/examples/ota-requestor-app/mbed/main/AppTask.cpp @@ -20,13 +20,13 @@ #include #include -#include #include #include #include #include #include #include +#include // mbed-os headers #include "drivers/Timeout.h" diff --git a/examples/platform/asr/init_Matter.cpp b/examples/platform/asr/init_Matter.cpp index 85fbb241ce..48682ef9c1 100644 --- a/examples/platform/asr/init_Matter.cpp +++ b/examples/platform/asr/init_Matter.cpp @@ -19,13 +19,13 @@ #include "AppConfig.h" #include #include -#include #include #include #include #include #include #include +#include #ifdef CONFIG_ENABLE_CHIP_SHELL #include #endif diff --git a/examples/platform/asr/shell/matter_shell.cpp b/examples/platform/asr/shell/matter_shell.cpp index bfa138f92f..8d3c91f96a 100644 --- a/examples/platform/asr/shell/matter_shell.cpp +++ b/examples/platform/asr/shell/matter_shell.cpp @@ -28,10 +28,10 @@ #include #include #include -#include #include #include #include +#include #include #include #if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR diff --git a/examples/platform/bouffalolab/common/plat/platform.cpp b/examples/platform/bouffalolab/common/plat/platform.cpp index 39ec050dfb..13b07ec0a3 100644 --- a/examples/platform/bouffalolab/common/plat/platform.cpp +++ b/examples/platform/bouffalolab/common/plat/platform.cpp @@ -18,12 +18,12 @@ #include #include #include -#include #include #include #include #include #include +#include #include #if HEAP_MONITORING diff --git a/examples/platform/infineon/cyw30739/cyw30739_example.gni b/examples/platform/infineon/cyw30739/cyw30739_example.gni index ff07ff6eb2..20fb494f43 100644 --- a/examples/platform/infineon/cyw30739/cyw30739_example.gni +++ b/examples/platform/infineon/cyw30739/cyw30739_example.gni @@ -39,6 +39,7 @@ template("cyw30739_example") { deps = [ "${chip_root}/examples/providers:device_info_provider", "${chip_root}/examples/shell/shell_common:shell_common", + "${chip_root}/src/setup_payload:onboarding-codes-utils", "${matter_wpan_sdk_build_root}:${board}", app_data_model, ] diff --git a/examples/platform/infineon/cyw30739/matter_config.cpp b/examples/platform/infineon/cyw30739/matter_config.cpp index 23fe5308ba..18d8dc2b22 100644 --- a/examples/platform/infineon/cyw30739/matter_config.cpp +++ b/examples/platform/infineon/cyw30739/matter_config.cpp @@ -37,7 +37,6 @@ #include "wiced_hal_i2c.h" #endif #include -#include #include #include #include @@ -48,6 +47,7 @@ #include #include #include +#include #include #ifdef BOARD_USE_OPTIGA diff --git a/examples/platform/linux/AppMain.cpp b/examples/platform/linux/AppMain.cpp index b4fb0cb13b..b0e4274a84 100644 --- a/examples/platform/linux/AppMain.cpp +++ b/examples/platform/linux/AppMain.cpp @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include @@ -31,6 +30,7 @@ #include #include #include +#include #include diff --git a/examples/platform/linux/BUILD.gn b/examples/platform/linux/BUILD.gn index ec4659e602..4ae6bd832c 100644 --- a/examples/platform/linux/BUILD.gn +++ b/examples/platform/linux/BUILD.gn @@ -115,6 +115,7 @@ source_set("app-main") { "${chip_root}/examples/providers:device_info_provider", "${chip_root}/src/app/server", "${chip_root}/src/app/tests/suites/credentials:dac_provider", + "${chip_root}/src/setup_payload:onboarding-codes-utils", ] if (current_os != "nuttx") { diff --git a/examples/platform/linux/CommissionerMain.cpp b/examples/platform/linux/CommissionerMain.cpp index 75719017a5..7475ffedc0 100644 --- a/examples/platform/linux/CommissionerMain.cpp +++ b/examples/platform/linux/CommissionerMain.cpp @@ -22,7 +22,6 @@ #include #include -#include #include #include #include @@ -31,6 +30,7 @@ #include #include #include +#include #include #include diff --git a/examples/platform/linux/Options.cpp b/examples/platform/linux/Options.cpp index fa56b62fea..2101c2cbdd 100644 --- a/examples/platform/linux/Options.cpp +++ b/examples/platform/linux/Options.cpp @@ -23,7 +23,7 @@ #include "Options.h" -#include +#include #include #include diff --git a/examples/platform/nxp/common/app_task/source/AppTaskBase.cpp b/examples/platform/nxp/common/app_task/source/AppTaskBase.cpp index 8490e1f111..8d816042a3 100644 --- a/examples/platform/nxp/common/app_task/source/AppTaskBase.cpp +++ b/examples/platform/nxp/common/app_task/source/AppTaskBase.cpp @@ -26,9 +26,9 @@ #include #include -#include #include #include +#include #include diff --git a/examples/platform/nxp/se05x/linux/AppMain.cpp b/examples/platform/nxp/se05x/linux/AppMain.cpp index 2d45f7dfed..47a67f64af 100644 --- a/examples/platform/nxp/se05x/linux/AppMain.cpp +++ b/examples/platform/nxp/se05x/linux/AppMain.cpp @@ -20,7 +20,6 @@ #include #include -#include #include #include #include @@ -28,6 +27,7 @@ #include #include #include +#include #include #include diff --git a/examples/platform/nxp/se05x/linux/BUILD.gn b/examples/platform/nxp/se05x/linux/BUILD.gn index a5efe46074..9c98d0ebfa 100644 --- a/examples/platform/nxp/se05x/linux/BUILD.gn +++ b/examples/platform/nxp/se05x/linux/BUILD.gn @@ -71,6 +71,8 @@ source_set("app-main") { defines += [ "ENABLE_CHIP_SHELL" ] } + deps = [ "${chip_root}/src/setup_payload:onboarding-codes-utils" ] + public_deps = [ ":ota-test-event-trigger", "${chip_root}/examples/providers:device_info_provider", diff --git a/examples/platform/openiotsdk/app/openiotsdk_platform.cpp b/examples/platform/openiotsdk/app/openiotsdk_platform.cpp index d9a268c7c2..40414c2870 100644 --- a/examples/platform/openiotsdk/app/openiotsdk_platform.cpp +++ b/examples/platform/openiotsdk/app/openiotsdk_platform.cpp @@ -42,11 +42,11 @@ #include #ifdef USE_CHIP_DATA_MODEL -#include #include #include #include #include +#include #endif // USE_CHIP_DATA_MODEL #ifdef CHIP_OPEN_IOT_SDK_OTA_ENABLE diff --git a/examples/platform/silabs/BaseApplication.cpp b/examples/platform/silabs/BaseApplication.cpp index 9ceef7fc7d..600a6653c9 100644 --- a/examples/platform/silabs/BaseApplication.cpp +++ b/examples/platform/silabs/BaseApplication.cpp @@ -44,12 +44,12 @@ #endif // ENABLE_CHIP_SHELL #endif // CHIP_CONFIG_ENABLE_ICD_SERVER -#include #include #include #include #include #include +#include #include #include #include diff --git a/examples/platform/telink/common/src/AppTaskCommon.cpp b/examples/platform/telink/common/src/AppTaskCommon.cpp index 860fc7115e..c5807b035b 100644 --- a/examples/platform/telink/common/src/AppTaskCommon.cpp +++ b/examples/platform/telink/common/src/AppTaskCommon.cpp @@ -34,11 +34,11 @@ #include #include #include -#include #include #include #include #include +#include #if CONFIG_BOOTLOADER_MCUBOOT #include diff --git a/examples/pump-app/cc13x4_26x4/main/AppTask.cpp b/examples/pump-app/cc13x4_26x4/main/AppTask.cpp index 08bd6ea4ba..260f59d358 100644 --- a/examples/pump-app/cc13x4_26x4/main/AppTask.cpp +++ b/examples/pump-app/cc13x4_26x4/main/AppTask.cpp @@ -48,7 +48,7 @@ #include #include -#include +#include #include #include diff --git a/examples/pump-app/nrfconnect/main/AppTask.cpp b/examples/pump-app/nrfconnect/main/AppTask.cpp index 3aa16dba35..9bd3de9fd0 100644 --- a/examples/pump-app/nrfconnect/main/AppTask.cpp +++ b/examples/pump-app/nrfconnect/main/AppTask.cpp @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include @@ -36,6 +35,7 @@ #include #include #include +#include #include #if CONFIG_CHIP_OTA_REQUESTOR diff --git a/examples/pump-app/silabs/src/AppTask.cpp b/examples/pump-app/silabs/src/AppTask.cpp index 1b4881ff77..df76fcca21 100644 --- a/examples/pump-app/silabs/src/AppTask.cpp +++ b/examples/pump-app/silabs/src/AppTask.cpp @@ -26,9 +26,9 @@ #include "LEDWidget.h" #include -#include #include #include +#include #include diff --git a/examples/pump-controller-app/cc13x4_26x4/main/AppTask.cpp b/examples/pump-controller-app/cc13x4_26x4/main/AppTask.cpp index 0e9097e3cb..4ccf7c8b89 100644 --- a/examples/pump-controller-app/cc13x4_26x4/main/AppTask.cpp +++ b/examples/pump-controller-app/cc13x4_26x4/main/AppTask.cpp @@ -43,7 +43,7 @@ #include #include -#include +#include #include #include diff --git a/examples/pump-controller-app/nrfconnect/main/AppTask.cpp b/examples/pump-controller-app/nrfconnect/main/AppTask.cpp index e22c3c75e3..37c5570032 100644 --- a/examples/pump-controller-app/nrfconnect/main/AppTask.cpp +++ b/examples/pump-controller-app/nrfconnect/main/AppTask.cpp @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include @@ -36,6 +35,7 @@ #include #include #include +#include #include #if CONFIG_CHIP_OTA_REQUESTOR diff --git a/examples/refrigerator-app/asr/src/AppTask.cpp b/examples/refrigerator-app/asr/src/AppTask.cpp index 5ac229c9b9..0141774b72 100644 --- a/examples/refrigerator-app/asr/src/AppTask.cpp +++ b/examples/refrigerator-app/asr/src/AppTask.cpp @@ -21,11 +21,11 @@ #include "CHIPDeviceManager.h" #include "DeviceCallbacks.h" #include "qrcodegen.h" -#include #include #include #include #include +#include #include #include diff --git a/examples/refrigerator-app/silabs/src/AppTask.cpp b/examples/refrigerator-app/silabs/src/AppTask.cpp index c9dc451b71..34e71cd591 100644 --- a/examples/refrigerator-app/silabs/src/AppTask.cpp +++ b/examples/refrigerator-app/silabs/src/AppTask.cpp @@ -42,7 +42,6 @@ #include #include #include -#include #include #include #include @@ -50,6 +49,7 @@ #include #include #include +#include #include #include diff --git a/examples/shell/cc13x4_26x4/main/AppTask.cpp b/examples/shell/cc13x4_26x4/main/AppTask.cpp index c3f7a3da5b..120d09db54 100644 --- a/examples/shell/cc13x4_26x4/main/AppTask.cpp +++ b/examples/shell/cc13x4_26x4/main/AppTask.cpp @@ -22,13 +22,13 @@ #include "FreeRTOS.h" -#include #include #include #include #include #include #include +#include #if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR #include @@ -41,7 +41,6 @@ #include #include -#include #include /* syscfg */ diff --git a/examples/smoke-co-alarm-app/silabs/src/AppTask.cpp b/examples/smoke-co-alarm-app/silabs/src/AppTask.cpp index 105a3c9e5b..7ef8b1c7a0 100644 --- a/examples/smoke-co-alarm-app/silabs/src/AppTask.cpp +++ b/examples/smoke-co-alarm-app/silabs/src/AppTask.cpp @@ -21,13 +21,13 @@ #include "LEDWidget.h" #include -#include #include #include #include #include #include #include +#include #include #include diff --git a/examples/temperature-measurement-app/asr/src/AppTask.cpp b/examples/temperature-measurement-app/asr/src/AppTask.cpp old mode 100755 new mode 100644 index e55657e45b..f04c3d98e6 --- a/examples/temperature-measurement-app/asr/src/AppTask.cpp +++ b/examples/temperature-measurement-app/asr/src/AppTask.cpp @@ -22,11 +22,11 @@ #include "CHIPDeviceManager.h" #include "DeviceCallbacks.h" #include "qrcodegen.h" -#include #include #include #include #include +#include #include #include diff --git a/examples/thermostat/asr/src/AppTask.cpp b/examples/thermostat/asr/src/AppTask.cpp old mode 100755 new mode 100644 index 6117fbf972..b74a51f575 --- a/examples/thermostat/asr/src/AppTask.cpp +++ b/examples/thermostat/asr/src/AppTask.cpp @@ -25,12 +25,12 @@ #include "qrcodegen.h" #include -#include #include #include #include #include #include +#include #include #include diff --git a/examples/thermostat/genio/src/AppTask.cpp b/examples/thermostat/genio/src/AppTask.cpp index 2cd1c479f9..75c736b794 100644 --- a/examples/thermostat/genio/src/AppTask.cpp +++ b/examples/thermostat/genio/src/AppTask.cpp @@ -26,10 +26,10 @@ #include #include -#include #include #include #include +#include #include diff --git a/examples/thermostat/nxp/rt/rt1060/BUILD.gn b/examples/thermostat/nxp/rt/rt1060/BUILD.gn index 83f9da9bc2..3e881afe08 100644 --- a/examples/thermostat/nxp/rt/rt1060/BUILD.gn +++ b/examples/thermostat/nxp/rt/rt1060/BUILD.gn @@ -197,7 +197,10 @@ rt_executable("thermostat") { "${common_example_dir}/matter_button/source/ButtonRegistrationDefault.cpp", ] - deps = [ "${chip_root}/examples/${app_common_folder}" ] + deps = [ + "${chip_root}/examples/${app_common_folder}", + "${chip_root}/src/setup_payload:onboarding-codes-utils", + ] if (nxp_enable_matter_cli) { defines += [ "ENABLE_CHIP_SHELL" ] diff --git a/examples/thermostat/nxp/rt/rt1170/BUILD.gn b/examples/thermostat/nxp/rt/rt1170/BUILD.gn index 3e03df4348..3db3b8640a 100644 --- a/examples/thermostat/nxp/rt/rt1170/BUILD.gn +++ b/examples/thermostat/nxp/rt/rt1170/BUILD.gn @@ -183,7 +183,10 @@ rt_executable("thermostat") { "${common_example_dir}/matter_button/source/ButtonRegistrationEmpty.cpp", ] - deps = [ "${chip_root}/examples/${app_common_folder}" ] + deps = [ + "${chip_root}/examples/${app_common_folder}", + "${chip_root}/src/setup_payload:onboarding-codes-utils", + ] if (nxp_enable_matter_cli) { defines += [ "ENABLE_CHIP_SHELL" ] diff --git a/examples/thermostat/nxp/rt/rw61x/BUILD.gn b/examples/thermostat/nxp/rt/rw61x/BUILD.gn index 6dd71061c0..911b1d60d5 100644 --- a/examples/thermostat/nxp/rt/rw61x/BUILD.gn +++ b/examples/thermostat/nxp/rt/rw61x/BUILD.gn @@ -207,6 +207,7 @@ rt_executable("thermostat") { deps = [ "${chip_root}/examples/${app_common_folder}", "${chip_root}/src/platform/logging:default", + "${chip_root}/src/setup_payload:onboarding-codes-utils", ] if (nxp_enable_matter_cli) { diff --git a/examples/thermostat/qpg/src/AppTask.cpp b/examples/thermostat/qpg/src/AppTask.cpp index 41342e410c..695a9ae48a 100644 --- a/examples/thermostat/qpg/src/AppTask.cpp +++ b/examples/thermostat/qpg/src/AppTask.cpp @@ -24,7 +24,7 @@ #include "AppTask.h" #include "ota.h" -#include +#include #include #include diff --git a/examples/thermostat/silabs/src/AppTask.cpp b/examples/thermostat/silabs/src/AppTask.cpp index e033a3fe2b..2a704b6550 100644 --- a/examples/thermostat/silabs/src/AppTask.cpp +++ b/examples/thermostat/silabs/src/AppTask.cpp @@ -39,13 +39,13 @@ #include #include #include -#include #include #include #include #include #include #include +#include #include #include diff --git a/examples/thread-br-app/esp32/main/main.cpp b/examples/thread-br-app/esp32/main/main.cpp index 3c3e95b973..6d7763c3e7 100644 --- a/examples/thread-br-app/esp32/main/main.cpp +++ b/examples/thread-br-app/esp32/main/main.cpp @@ -35,11 +35,11 @@ #include "support/CHIPMem.h" #include -#include #include #include #include #include +#include #if CONFIG_ENABLE_ESP32_FACTORY_DATA_PROVIDER #include diff --git a/examples/window-app/nrfconnect/main/AppTask.cpp b/examples/window-app/nrfconnect/main/AppTask.cpp index 2b6fb6ba66..93a005bd5f 100644 --- a/examples/window-app/nrfconnect/main/AppTask.cpp +++ b/examples/window-app/nrfconnect/main/AppTask.cpp @@ -27,12 +27,12 @@ #include #include #include -#include #include #include #include #include #include +#include #if CONFIG_CHIP_OTA_REQUESTOR #include "OTAUtil.h" diff --git a/examples/window-app/silabs/src/AppTask.cpp b/examples/window-app/silabs/src/AppTask.cpp index 214a405b61..de1bdcb4a8 100644 --- a/examples/window-app/silabs/src/AppTask.cpp +++ b/examples/window-app/silabs/src/AppTask.cpp @@ -23,9 +23,9 @@ #include "WindowManager.h" -#include #include #include +#include #include diff --git a/examples/window-app/silabs/src/WindowManager.cpp b/examples/window-app/silabs/src/WindowManager.cpp index f3a4faf3c1..3bf20aa809 100644 --- a/examples/window-app/silabs/src/WindowManager.cpp +++ b/examples/window-app/silabs/src/WindowManager.cpp @@ -27,12 +27,12 @@ #include #include -#include #include #include #include #include #include +#include #ifdef SL_WIFI #include diff --git a/src/app/chip_data_model.cmake b/src/app/chip_data_model.cmake index 65d3c0ada5..317120c4cf 100644 --- a/src/app/chip_data_model.cmake +++ b/src/app/chip_data_model.cmake @@ -86,7 +86,6 @@ function(chip_configure_data_model APP_TARGET) ${CHIP_APP_BASE_DIR}/server/DefaultTermsAndConditionsProvider.cpp ${CHIP_APP_BASE_DIR}/server/Dnssd.cpp ${CHIP_APP_BASE_DIR}/server/EchoHandler.cpp - ${CHIP_APP_BASE_DIR}/server/OnboardingCodesUtil.cpp ${CHIP_APP_BASE_DIR}/server/Server.cpp ) diff --git a/src/app/server/BUILD.gn b/src/app/server/BUILD.gn index 040c7b2227..1190bec299 100644 --- a/src/app/server/BUILD.gn +++ b/src/app/server/BUILD.gn @@ -57,8 +57,6 @@ static_library("server") { "Dnssd.h", "EchoHandler.cpp", "EchoHandler.h", - "OnboardingCodesUtil.cpp", - "OnboardingCodesUtil.h", "Server.cpp", "Server.h", ] @@ -81,7 +79,6 @@ static_library("server") { "${chip_root}/src/messaging", "${chip_root}/src/platform", "${chip_root}/src/protocols", - "${chip_root}/src/setup_payload", "${chip_root}/src/transport", ] diff --git a/src/app/server/java/AndroidAppServerWrapper.cpp b/src/app/server/java/AndroidAppServerWrapper.cpp index 15d2d8fa69..10e08821ad 100644 --- a/src/app/server/java/AndroidAppServerWrapper.cpp +++ b/src/app/server/java/AndroidAppServerWrapper.cpp @@ -18,7 +18,6 @@ #include "AndroidAppServerWrapper.h" -#include #include #include #include @@ -30,6 +29,7 @@ #include #include #include +#include #include #include #include diff --git a/src/controller/python/chip/server/ServerInit.cpp b/src/controller/python/chip/server/ServerInit.cpp index ca1efee777..4d13dea8a0 100644 --- a/src/controller/python/chip/server/ServerInit.cpp +++ b/src/controller/python/chip/server/ServerInit.cpp @@ -18,9 +18,9 @@ #include #include -#include #include #include +#include #include #include diff --git a/src/lib/BUILD.gn b/src/lib/BUILD.gn index fc9d128983..759f65ed8e 100644 --- a/src/lib/BUILD.gn +++ b/src/lib/BUILD.gn @@ -30,6 +30,7 @@ source_set("without-logging") { "${chip_root}/src/platform", "${chip_root}/src/protocols", "${chip_root}/src/setup_payload", + "${chip_root}/src/setup_payload:onboarding-codes-utils", "${chip_root}/src/system", "${chip_root}/src/transport", ] diff --git a/src/lib/shell/MainLoopMW320.cpp b/src/lib/shell/MainLoopMW320.cpp index 833c87a3bc..8445587b40 100644 --- a/src/lib/shell/MainLoopMW320.cpp +++ b/src/lib/shell/MainLoopMW320.cpp @@ -16,7 +16,6 @@ */ #include "streamer.h" -#include #include #include #include @@ -161,7 +160,7 @@ static void AtExitShell(void); static CHIP_ERROR ShutdownHandler(int argc, char ** argv) { streamer_printf(streamer_get(), "Shutdown and Goodbye\r\n"); - Server::GetInstance().GenerateShutDownEvent(); + DeviceLayer::PlatformMgr().ScheduleWork([](intptr_t) { DeviceLayer::PlatformMgr().HandleServerShuttingDown(); }); // TODO: This is assuming that we did (on a different thread from this one) // RunEventLoop(), not StartEventLoopTask(). It will not work correctly // with StartEventLoopTask(). diff --git a/src/lib/shell/commands/BUILD.gn b/src/lib/shell/commands/BUILD.gn index a0a8052a64..a2f5a9d597 100644 --- a/src/lib/shell/commands/BUILD.gn +++ b/src/lib/shell/commands/BUILD.gn @@ -65,7 +65,7 @@ source_set("commands") { } if (chip_device_platform != "none") { - public_deps += [ "${chip_root}/src/app/server" ] + deps = [ "${chip_root}/src/setup_payload:onboarding-codes-utils" ] } cflags = [ "-Wconversion" ] diff --git a/src/lib/shell/commands/NFC.cpp b/src/lib/shell/commands/NFC.cpp index 5311c638e8..60c9facb9a 100644 --- a/src/lib/shell/commands/NFC.cpp +++ b/src/lib/shell/commands/NFC.cpp @@ -20,9 +20,9 @@ #if CONFIG_DEVICE_LAYER #include #endif -#include #include #include +#include using chip::DeviceLayer::ConnectivityMgr; diff --git a/src/lib/shell/commands/OnboardingCodes.cpp b/src/lib/shell/commands/OnboardingCodes.cpp index a08a63be68..1f314d4c11 100644 --- a/src/lib/shell/commands/OnboardingCodes.cpp +++ b/src/lib/shell/commands/OnboardingCodes.cpp @@ -15,7 +15,6 @@ * limitations under the License. */ -#include #include #include #include @@ -24,6 +23,7 @@ #include #include #include +#include #include #define CHIP_SHELL_MAX_BUFFER_SIZE 128 diff --git a/src/setup_payload/BUILD.gn b/src/setup_payload/BUILD.gn index 30b97ceca7..e42e2e9cea 100644 --- a/src/setup_payload/BUILD.gn +++ b/src/setup_payload/BUILD.gn @@ -79,3 +79,16 @@ static_library("setup_payload") { "${chip_root}/src/lib/support", ] } + +source_set("onboarding-codes-utils") { + sources = [ + "OnboardingCodesUtil.cpp", + "OnboardingCodesUtil.h", + ] + + deps = [ "${chip_root}/src/platform" ] + + public_deps = [ "${chip_root}/src/setup_payload" ] + + public_configs = [ "${chip_root}/src:includes" ] +} diff --git a/src/app/server/OnboardingCodesUtil.cpp b/src/setup_payload/OnboardingCodesUtil.cpp similarity index 99% rename from src/app/server/OnboardingCodesUtil.cpp rename to src/setup_payload/OnboardingCodesUtil.cpp index 7f78da4169..70e0bf7b3e 100644 --- a/src/app/server/OnboardingCodesUtil.cpp +++ b/src/setup_payload/OnboardingCodesUtil.cpp @@ -16,7 +16,7 @@ * limitations under the License. */ -#include +#include #include #include diff --git a/src/app/server/OnboardingCodesUtil.h b/src/setup_payload/OnboardingCodesUtil.h similarity index 100% rename from src/app/server/OnboardingCodesUtil.h rename to src/setup_payload/OnboardingCodesUtil.h From 9799dce84719b1dd67203c4f8227c72647195421 Mon Sep 17 00:00:00 2001 From: Nivi Sarkar <55898241+nivi-apple@users.noreply.github.com> Date: Fri, 7 Feb 2025 09:54:35 -0800 Subject: [PATCH 28/39] =?UTF-8?q?Add=20test=20steps=2050-60=20from=20the?= =?UTF-8?q?=20Thermostat=20test=20plan=20to=20the=20Thermostat=20=E2=80=A6?= =?UTF-8?q?=20(#37052)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add test steps 50-60 from the Thermostat test plan to the Thermostat YAML script - Remove Test_TC_TSTAT_4_1.yaml * Restyle * Rename TC_TSTAT_4_2.py to TC_TSTAT_2_3.py * Address review comments * Revert renaming TC_TSTAT_4_2.py to TC_TSTAT_2_3.py * Add check for the Presets list length that should not exceed the value in NumberOfPresets attribute * Editorial fix * Revert the name change from TC_TSTAT_4_2 to TC_TSTAT_2_3 * Update minLength and maxLength in YAML to take a variable as input * Restyle --- .../matter_yamltests/yaml_loader.py | 4 +- src/app/tests/suites/certification/PICS.yaml | 21 +- .../certification/Test_TC_TSTAT_2_1.yaml | 198 +++++++++++++----- .../certification/Test_TC_TSTAT_4_1.yaml | 110 ---------- .../tests/suites/certification/ci-pics-values | 5 + src/python_testing/TC_TSTAT_4_2.py | 2 +- 6 files changed, 177 insertions(+), 163 deletions(-) delete mode 100644 src/app/tests/suites/certification/Test_TC_TSTAT_4_1.yaml diff --git a/scripts/py_matter_yamltests/matter_yamltests/yaml_loader.py b/scripts/py_matter_yamltests/matter_yamltests/yaml_loader.py index ee8449e78a..2ac318db22 100644 --- a/scripts/py_matter_yamltests/matter_yamltests/yaml_loader.py +++ b/scripts/py_matter_yamltests/matter_yamltests/yaml_loader.py @@ -92,8 +92,8 @@ _TEST_STEP_RESPONSE_CONSTRAINTS_SCHEMA = { 'hasValue': bool, 'type': str, - 'minLength': int, - 'maxLength': int, + 'minLength': (int, str), # Can be a variable. + 'maxLength': (int, str), # Can be a variable. 'isHexString': bool, 'startsWith': str, 'endsWith': str, diff --git a/src/app/tests/suites/certification/PICS.yaml b/src/app/tests/suites/certification/PICS.yaml index e211192595..9faf23bd10 100644 --- a/src/app/tests/suites/certification/PICS.yaml +++ b/src/app/tests/suites/certification/PICS.yaml @@ -6489,21 +6489,36 @@ PICS: - label: "Does the device implement the PresetTypes attribute?" id: TSTAT.S.A0048 + - label: "Does the device implement the ScheduleTypes attribute?" + id: TSTAT.S.A0049 + - label: "Does the device implement the NumberOfPresets attribute?" id: TSTAT.S.A004a + - label: "Does the device implement the NumberOfSchedules attribute?" + id: TSTAT.S.A004b + + - label: + "Does the device implement the NumberOfScheduleTransitions attribute?" + id: TSTAT.S.A004c + + - label: + "Does the device implement the NumberOfScheduleTransitionPerDay + attribute?" + id: TSTAT.S.A004d + - label: "Does the device implement the ActivePresetHandle attribute?" id: TSTAT.S.A004e + - label: "Does the device implement the ActiveScheduleHandle attribute?" + id: TSTAT.S.A004f + - label: "Does the device implement the Presets attribute?" id: TSTAT.S.A0050 - label: "Does the device implement the Schedules attribute?" id: TSTAT.S.A0051 - - label: "Does the device implement the Schedules attribute?" - id: TSTAT.S.A0051 - - label: "Does the device implement the SetpointHoldExpiryTimestamp attribute?" id: TSTAT.S.A0052 diff --git a/src/app/tests/suites/certification/Test_TC_TSTAT_2_1.yaml b/src/app/tests/suites/certification/Test_TC_TSTAT_2_1.yaml index 2db131a5a4..ef7f8dae4c 100644 --- a/src/app/tests/suites/certification/Test_TC_TSTAT_2_1.yaml +++ b/src/app/tests/suites/certification/Test_TC_TSTAT_2_1.yaml @@ -119,6 +119,15 @@ tests: response: saveAs: UnoccupiedCoolingSetpointValue + - label: + "Saving value for comparision in step 58 read NumberOfPresets + attribute" + PICS: TSTAT.S.F08 + command: "readAttribute" + attribute: "NumberOfPresets" + response: + saveAs: NumberOfPresetsValue + - label: "Step 2: TH reads the LocalTemperature attribute from the DUT" command: "readAttribute" attribute: "LocalTemperature" @@ -235,7 +244,7 @@ tests: maxValue: 100 - label: - "Step 12: TH reads the LocalTemperatureCalibration attribute from the + "Step 11: TH reads the LocalTemperatureCalibration attribute from the DUT" PICS: TSTAT.S.A0010 command: "readAttribute" @@ -246,7 +255,7 @@ tests: minValue: -127 maxValue: 127 - - label: "Step 13a: TH reads attribute OccupiedCoolingSetpoint from the DUT" + - label: "Step 12a: TH reads attribute OccupiedCoolingSetpoint from the DUT" PICS: TSTAT.S.F01 && TSTAT.S.A0017 && TSTAT.S.A0018 command: "readAttribute" attribute: "OccupiedCoolingSetpoint" @@ -256,7 +265,7 @@ tests: minValue: MinCoolSetpointLimitValue maxValue: MaxCoolSetpointLimitValue - - label: "Step 13b: TH reads attribute OccupiedCoolingSetpoint from the DUT" + - label: "Step 12b: TH reads attribute OccupiedCoolingSetpoint from the DUT" PICS: TSTAT.S.F01 && !TSTAT.S.A0017 && !TSTAT.S.A0018 command: "readAttribute" attribute: "OccupiedCoolingSetpoint" @@ -267,7 +276,7 @@ tests: maxValue: 3200 - label: - "Step 14a: TH reads attribute OccupiedHeatingSetpoint if TSTAT.S.F05 + "Step 13a: TH reads attribute OccupiedHeatingSetpoint if TSTAT.S.F05 feature is supported" PICS: TSTAT.S.F05 && TSTAT.S.F00 command: "readAttribute" @@ -278,7 +287,7 @@ tests: minValue: AbsMinCoolSetpointLimitStep5 maxValue: OccupiedCoolingSetpointValue - MinSetpointDeadBandValue - - label: "Step 14b: TH reads attribute OccupiedHeatingSetpoint from the DUT" + - label: "Step 13b: TH reads attribute OccupiedHeatingSetpoint from the DUT" PICS: TSTAT.S.F00 && !TSTAT.S.F05 command: "readAttribute" attribute: "OccupiedHeatingSetpoint" @@ -289,7 +298,7 @@ tests: maxValue: 3000 - label: - "Step 15a: TH reads UnoccupiedCoolingSetpoint attribute from the DUT" + "Step 14a: TH reads UnoccupiedCoolingSetpoint attribute from the DUT" PICS: TSTAT.S.F05 && TSTAT.S.A0013 command: "readAttribute" attribute: "UnoccupiedCoolingSetpoint" @@ -300,7 +309,7 @@ tests: maxValue: AbsMaxHeatValue - label: - "Step 15b: TH reads UnoccupiedCoolingSetpoint attribute from the DUT" + "Step 14b: TH reads UnoccupiedCoolingSetpoint attribute from the DUT" PICS: TSTAT.S.F01 && TSTAT.S.F02 && !TSTAT.S.F05 command: "readAttribute" attribute: "UnoccupiedCoolingSetpoint" @@ -311,7 +320,7 @@ tests: maxValue: 3200 - label: - "Step 16a: TH reads UnoccupiedHeatingSetpoint attribute from the DUT" + "Step 15a: TH reads UnoccupiedHeatingSetpoint attribute from the DUT" PICS: TSTAT.S.F00 && TSTAT.S.F02 && TSTAT.S.F05 && TSTAT.S.A0013 command: "readAttribute" attribute: "UnoccupiedHeatingSetpoint" @@ -323,7 +332,7 @@ tests: UnoccupiedCoolingSetpointValue - MinSetpointDeadBandValue - label: - "Step 16b: TH reads UnoccupiedHeatingSetpoint attribute from the DUT" + "Step 15b: TH reads UnoccupiedHeatingSetpoint attribute from the DUT" PICS: TSTAT.S.F00 && TSTAT.S.F02 && !TSTAT.S.F05 command: "readAttribute" attribute: "UnoccupiedHeatingSetpoint" @@ -333,7 +342,7 @@ tests: minValue: 700 maxValue: 3000 - - label: "Step 17a: TH reads attribute from DUT: MinHeatSetpointLimit" + - label: "Step 16a: TH reads attribute from DUT: MinHeatSetpointLimit" PICS: TSTAT.S.A0015 && TSTAT.S.F05 && TSTAT.S.A0017 && TSTAT.S.A0019 command: "readAttribute" attribute: "MinHeatSetpointLimit" @@ -344,7 +353,7 @@ tests: maxValue: MinCoolSetpointLimitValue - MinSetpointDeadBandValue - label: - "Step 17b: TH reads MinHeatSetpointLimit attribute from Server DUT and + "Step 16b: TH reads MinHeatSetpointLimit attribute from Server DUT and verifies that the value is within range" command: "readAttribute" attribute: "MinHeatSetpointLimit" @@ -357,7 +366,7 @@ tests: #Using hard coded values when optional attributes are not available - label: - "Step 17c: TH reads MinHeatSetpointLimit attribute from Server DUT and + "Step 16c: TH reads MinHeatSetpointLimit attribute from Server DUT and verifies that the value is within range" command: "readAttribute" attribute: "MinHeatSetpointLimit" @@ -368,7 +377,7 @@ tests: minValue: 700 maxValue: 3000 - - label: "Step 18a: TH reads attribute MaxHeatSetpointLimit from the DUT" + - label: "Step 17a: TH reads attribute MaxHeatSetpointLimit from the DUT" PICS: TSTAT.S.A0016 && !TSTAT.S.F05 command: "readAttribute" attribute: "MaxHeatSetpointLimit" @@ -378,7 +387,7 @@ tests: minValue: 700 maxValue: 3000 - - label: "Step 18b: TH reads attribute from DUT: MaxHeatSetpointLimit" + - label: "Step 17b: TH reads attribute from DUT: MaxHeatSetpointLimit" PICS: TSTAT.S.A0016 && TSTAT.S.F05 && TSTAT.S.A0018 command: "readAttribute" attribute: "MaxHeatSetpointLimit" @@ -388,7 +397,7 @@ tests: minValue: 700 maxValue: MaxCoolSetpointLimitValue - MinSetpointDeadBandValue - - label: "Step 19a: TH reads attribute MinCoolSetpointLimit from DUT" + - label: "Step 18a: TH reads attribute MinCoolSetpointLimit from DUT" PICS: TSTAT.S.A0017 && TSTAT.S.A0018 && TSTAT.S.A0005 command: "readAttribute" attribute: "MinCoolSetpointLimit" @@ -398,7 +407,7 @@ tests: minValue: AbsMinCoolSetpointLimitStep5 maxValue: MaxCoolSetpointLimitValue - - label: "Step 19b: TH reads attribute MinCoolSetpointLimit from DUT" + - label: "Step 18b: TH reads attribute MinCoolSetpointLimit from DUT" PICS: TSTAT.S.A0017 && !TSTAT.S.A0018 && !TSTAT.S.A0005 command: "readAttribute" attribute: "MinCoolSetpointLimit" @@ -408,7 +417,7 @@ tests: minValue: 1600 maxValue: 3200 - - label: "Step 20: TH reads the MaxCoolSetpointLimit attribute from the DUT" + - label: "Step 19: TH reads the MaxCoolSetpointLimit attribute from the DUT" PICS: TSTAT.S.A0018 && TSTAT.S.A0006 && TSTAT.S.A0017 command: "readAttribute" attribute: "MaxCoolSetpointLimit" @@ -418,7 +427,7 @@ tests: minValue: MinCoolSetpointLimitValue maxValue: AbsMaxCoolSetpointLimitStep6 - - label: "Step 21: TH reads the MinSetpointDeadBand attribute from the DUT" + - label: "Step 20: TH reads the MinSetpointDeadBand attribute from the DUT" PICS: TSTAT.S.F05 command: "readAttribute" attribute: "MinSetpointDeadBand" @@ -428,7 +437,7 @@ tests: minValue: 0 maxValue: 25 - - label: "Step 22: TH reads the RemoteSensing attribute from the DUT" + - label: "Step 21: TH reads the RemoteSensing attribute from the DUT" PICS: TSTAT.S.A001a command: "readAttribute" attribute: "RemoteSensing" @@ -439,7 +448,7 @@ tests: maxValue: 7 - label: - "Step 23: TH reads the ControlSequenceOfOperation attribute from the + "Step 22: TH reads the ControlSequenceOfOperation attribute from the DUT" PICS: TSTAT.S.A001b command: "readAttribute" @@ -450,7 +459,7 @@ tests: minValue: 0 maxValue: 5 - - label: "Step 24: TH reads the SystemMode attribute from the DUT" + - label: "Step 23: TH reads the SystemMode attribute from the DUT" PICS: TSTAT.S.A001c command: "readAttribute" attribute: "SystemMode" @@ -461,7 +470,7 @@ tests: maxValue: 9 - label: - "Step 26: TH reads the ThermostatRunningMode attribute from the DUT" + "Step 24: TH reads the ThermostatRunningMode attribute from the DUT" PICS: TSTAT.S.A001e command: "readAttribute" attribute: "ThermostatRunningMode" @@ -475,7 +484,7 @@ tests: ThermostatRunningModeEnum.Heat(4), ] - - label: "Step 27: TH reads the StartOfWeek attribute from the DUT" + - label: "Step 25: TH reads the StartOfWeek attribute from the DUT" PICS: TSTAT.S.F03 command: "readAttribute" attribute: "StartOfWeek" @@ -486,7 +495,7 @@ tests: maxValue: 6 - label: - "Step 28: TH reads the NumberOfWeeklyTransitions attribute from the + "Step 26: TH reads the NumberOfWeeklyTransitions attribute from the DUT" PICS: TSTAT.S.F03 command: "readAttribute" @@ -498,7 +507,7 @@ tests: maxValue: 255 - label: - "Step 29: TH reads the NumberOfDailyTransitions attribute from the DUT" + "Step 27: TH reads the NumberOfDailyTransitions attribute from the DUT" PICS: TSTAT.S.F03 command: "readAttribute" attribute: "NumberOfDailyTransitions" @@ -509,7 +518,7 @@ tests: maxValue: 255 - label: - "Step 30: TH reads the TemperatureSetpointHold attribute from the DUT" + "Step 28: TH reads the TemperatureSetpointHold attribute from the DUT" PICS: TSTAT.S.A0023 command: "readAttribute" attribute: "TemperatureSetpointHold" @@ -520,7 +529,7 @@ tests: maxValue: 1 - label: - "Step 31: TH reads the TemperatureSetpointHoldDuration attribute from + "Step 29: TH reads the TemperatureSetpointHoldDuration attribute from the DUT" PICS: TSTAT.S.A0024 command: "readAttribute" @@ -532,7 +541,7 @@ tests: maxValue: 1440 - label: - "Step 32: TH reads the ThermostatProgrammingOperationMode attribute + "Step 30: TH reads the ThermostatProgrammingOperationMode attribute from the DUT" PICS: TSTAT.S.A0025 command: "readAttribute" @@ -544,7 +553,7 @@ tests: maxValue: 7 - label: - "Step 33: TH reads the ThermostatRunningState attribute from the DUT" + "Step 31: TH reads the ThermostatRunningState attribute from the DUT" PICS: TSTAT.S.A0029 command: "readAttribute" attribute: "ThermostatRunningState" @@ -554,7 +563,7 @@ tests: minValue: 0 maxValue: 127 - - label: "Step 34: TH reads the SetpointChangeSource attribute from the DUT" + - label: "Step 32: TH reads the SetpointChangeSource attribute from the DUT" PICS: TSTAT.S.A0030 command: "readAttribute" attribute: "SetpointChangeSource" @@ -564,7 +573,7 @@ tests: minValue: 0 maxValue: 2 - - label: "Step 35: TH reads the SetpointChangeAmount attribute from the DUT" + - label: "Step 33: TH reads the SetpointChangeAmount attribute from the DUT" PICS: TSTAT.S.A0031 command: "readAttribute" attribute: "SetpointChangeAmount" @@ -575,7 +584,7 @@ tests: maxValue: 32767 - label: - "Step 36: TH reads the SetpointChangeSourceTimestamp attribute from + "Step 34: TH reads the SetpointChangeSourceTimestamp attribute from the DUT" PICS: TSTAT.S.A0032 command: "readAttribute" @@ -584,7 +593,7 @@ tests: constraints: type: epoch_s - - label: "Step 37: TH reads the OccupiedSetback attribute from the DUT" + - label: "Step 35: TH reads the OccupiedSetback attribute from the DUT" PICS: TSTAT.S.F04 command: "readAttribute" attribute: "OccupiedSetback" @@ -594,7 +603,7 @@ tests: minValue: 0 maxValue: 255 - - label: "Step 38: TH reads the OccupiedSetbackMin attribute from the DUT" + - label: "Step 36: TH reads the OccupiedSetbackMin attribute from the DUT" PICS: TSTAT.S.F04 command: "readAttribute" attribute: "OccupiedSetbackMin" @@ -604,7 +613,7 @@ tests: minValue: 0 maxValue: 255 - - label: "Step 39: TH reads the OccupiedSetbackMax attribute from the DUT" + - label: "Step 37: TH reads the OccupiedSetbackMax attribute from the DUT" PICS: TSTAT.S.F04 command: "readAttribute" attribute: "OccupiedSetbackMax" @@ -614,7 +623,7 @@ tests: minValue: 0 maxValue: 255 - - label: "Step 40: TH reads the UnoccupiedSetback attribute from the DUT" + - label: "Step 38: TH reads the UnoccupiedSetback attribute from the DUT" PICS: TSTAT.S.F02 && TSTAT.S.F04 command: "readAttribute" attribute: "UnoccupiedSetback" @@ -624,7 +633,7 @@ tests: minValue: 0 maxValue: 255 - - label: "Step 41: TH reads the UnoccupiedSetbackMin attribute from the DUT" + - label: "Step 39: TH reads the UnoccupiedSetbackMin attribute from the DUT" PICS: TSTAT.S.F02 && TSTAT.S.F04 command: "readAttribute" attribute: "UnoccupiedSetbackMin" @@ -634,7 +643,7 @@ tests: minValue: 0 maxValue: 255 - - label: "Step 42: TH reads the UnoccupiedSetbackMax attribute from the DUT" + - label: "Step 40: TH reads the UnoccupiedSetbackMax attribute from the DUT" PICS: TSTAT.S.F02 && TSTAT.S.F04 command: "readAttribute" attribute: "UnoccupiedSetbackMax" @@ -644,7 +653,7 @@ tests: minValue: 0 maxValue: 255 - - label: "Step 43: TH reads the EmergencyHeatDelta attribute from the DUT" + - label: "Step 41: TH reads the EmergencyHeatDelta attribute from the DUT" PICS: TSTAT.S.A003a command: "readAttribute" attribute: "EmergencyHeatDelta" @@ -654,7 +663,7 @@ tests: minValue: 0 maxValue: 255 - - label: "Step 44: TH reads the ACType attribute from the DUT" + - label: "Step 42: TH reads the ACType attribute from the DUT" PICS: TSTAT.S.A0040 command: "readAttribute" attribute: "ACType" @@ -664,7 +673,7 @@ tests: minValue: 0 maxValue: 4 - - label: "Step 45: TH reads the ACCapacity attribute from the DUT" + - label: "Step 43: TH reads the ACCapacity attribute from the DUT" PICS: TSTAT.S.A0041 command: "readAttribute" attribute: "ACCapacity" @@ -674,7 +683,7 @@ tests: minValue: 0 maxValue: 65535 - - label: "Step 46: TH reads the ACRefrigerantType attribute from the DUT" + - label: "Step 44: TH reads the ACRefrigerantType attribute from the DUT" PICS: TSTAT.S.A0042 command: "readAttribute" attribute: "ACRefrigerantType" @@ -684,7 +693,7 @@ tests: minValue: 0 maxValue: 3 - - label: "Step 47: TH reads the ACCompressorType attribute from the DUT" + - label: "Step 45: TH reads the ACCompressorType attribute from the DUT" PICS: TSTAT.S.A0043 command: "readAttribute" attribute: "ACCompressorType" @@ -694,7 +703,7 @@ tests: minValue: 0 maxValue: 3 - - label: "Step 48: TH reads the ACErrorCode attribute from the DUT" + - label: "Step 46: TH reads the ACErrorCode attribute from the DUT" PICS: TSTAT.S.A0044 command: "readAttribute" attribute: "ACErrorCode" @@ -702,7 +711,7 @@ tests: constraints: type: bitmap32 - - label: "Step 49: TH reads the ACLouverPosition attribute from the DUT" + - label: "Step 47: TH reads the ACLouverPosition attribute from the DUT" PICS: TSTAT.S.A0045 command: "readAttribute" attribute: "ACLouverPosition" @@ -712,7 +721,7 @@ tests: minValue: 1 maxValue: 5 - - label: "Step 50: TH reads the ACCoilTemperature attribute from the DUT" + - label: "Step 48: TH reads the ACCoilTemperature attribute from the DUT" PICS: TSTAT.S.A0046 command: "readAttribute" attribute: "ACCoilTemperature" @@ -722,7 +731,7 @@ tests: minValue: -27315 maxValue: 32767 - - label: "Step 51: TH reads the ACCapacityFormat attribute from the DUT" + - label: "Step 49: TH reads the ACCapacityFormat attribute from the DUT" PICS: TSTAT.S.A0047 command: "readAttribute" attribute: "ACCapacityformat" @@ -730,3 +739,98 @@ tests: value: 0 constraints: type: enum8 + + - label: "Step 50: TH reads the PresetTypes attribute from the DUT" + PICS: TSTAT.S.F08 + command: "readAttribute" + attribute: "PresetTypes" + response: + constraints: + type: list + + - label: "Step 51: TH reads the ScheduleTypes attribute from the DUT" + PICS: TSTAT.S.F07 + command: "readAttribute" + attribute: "ScheduleTypes" + response: + constraints: + type: list + + - label: "Step 52: TH reads the NumberOfPresets attribute from the DUT" + PICS: TSTAT.S.F08 + command: "readAttribute" + attribute: "NumberOfPresets" + response: + constraints: + type: int8u + + - label: "Step 53: TH reads the NumberOfSchedules attribute from the DUT" + PICS: TSTAT.S.F07 + command: "readAttribute" + attribute: "NumberOfSchedules" + response: + constraints: + type: int8u + + - label: + "Step 54: TH reads the NumberOfScheduleTransitions attribute from the + DUT" + PICS: TSTAT.S.F07 + command: "readAttribute" + attribute: "NumberOfScheduleTransitions" + response: + constraints: + type: int8u + + - label: + "Step 55: TH reads the NumberOfScheduleTransitionPerDay attribute from + the DUT" + PICS: TSTAT.S.F07 + command: "readAttribute" + attribute: "NumberOfScheduleTransitionPerDay" + response: + constraints: + type: int8u + + - label: "Step 56: TH reads the ActivePresetHandle attribute from the DUT" + PICS: TSTAT.S.F08 + command: "readAttribute" + attribute: "ActivePresetHandle" + response: + constraints: + type: octstr + + - label: "Step 57: TH reads the ActiveScheduleHandle attribute from the DUT" + PICS: TSTAT.S.F07 + command: "readAttribute" + attribute: "ActiveScheduleHandle" + response: + constraints: + type: octstr + + - label: "Step 58: TH reads the Presets attribute from the DUT" + PICS: TSTAT.S.F08 + command: "readAttribute" + attribute: "Presets" + response: + constraints: + type: list + maxLength: NumberOfPresetsValue + + - label: "Step 59: TH reads the Schedules attribute from the DUT" + PICS: TSTAT.S.F07 + command: "readAttribute" + attribute: "Schedules" + response: + constraints: + type: list + + - label: + "Step 60: TH reads the SetpointHoldExpiryTimestamp attribute from the + DUT" + PICS: TSTAT.S.A0052 + command: "readAttribute" + attribute: "SetpointHoldExpiryTimestamp" + response: + constraints: + type: int32u diff --git a/src/app/tests/suites/certification/Test_TC_TSTAT_4_1.yaml b/src/app/tests/suites/certification/Test_TC_TSTAT_4_1.yaml deleted file mode 100644 index 50037d682d..0000000000 --- a/src/app/tests/suites/certification/Test_TC_TSTAT_4_1.yaml +++ /dev/null @@ -1,110 +0,0 @@ -# Copyright (c) 2024 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. - -name: 42.4.1. [TC-TSTAT-4.1] Preset attributes with server as DUT - -PICS: - - TSTAT.S - -config: - nodeId: 0x12344321 - cluster: "Thermostat" - endpoint: 1 - -tests: - - label: "Step 1: Commission DUT to TH" - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Saving value for comparision in step 2 read PresetTypes attribute" - PICS: TSTAT.S.A0048 - command: "readAttribute" - attribute: "PresetTypes" - response: - saveAs: PresetTypesValue - - - label: - "Saving value for comparision in step 3 read NumberOfPresets attribute" - PICS: TSTAT.S.A004a - command: "readAttribute" - attribute: "NumberOfPresets" - response: - saveAs: NumberOfPresetsValue - - - label: - "Saving value for comparision in step 4 read ActivePresetHandleValue - attribute" - PICS: TSTAT.S.A004e - command: "readAttribute" - attribute: "ActivePresetHandle" - response: - saveAs: ActivePresetHandleValue - - - label: "Saving value for comparision in step 5 read Presets attribute" - PICS: TSTAT.S.A0050 - command: "readAttribute" - attribute: "Presets" - response: - saveAs: PresetsValue - - - label: "Saving value for comparision in step 6 read Schedules attribute" - PICS: TSTAT.S.A0051 - command: "readAttribute" - attribute: "Schedules" - response: - saveAs: SchedulesValue - - - label: "Step 2: TH reads the PresetTypes attribute from the DUT" - PICS: TSTAT.S.F08 && TSTAT.S.A0048 - command: "readAttribute" - attribute: "PresetTypes" - response: - constraints: - type: list - - - label: "Step 3: TH reads the NumberOfPresets attribute from the DUT" - PICS: TSTAT.S.F08 && TSTAT.S.A004a - command: "readAttribute" - attribute: "NumberOfPresets" - response: - constraints: - type: int8u - - - label: "Step 4: TH reads the ActivePresetHandle attribute from the DUT" - PICS: TSTAT.S.F08 && TSTAT.S.A004e - command: "readAttribute" - attribute: "ActivePresetHandle" - response: - constraints: - type: octstr - - - label: "Step 5: TH reads the Presets attribute from the DUT" - PICS: TSTAT.S.F08 && TSTAT.S.A0050 - command: "readAttribute" - attribute: "Presets" - response: - constraints: - type: list - - - label: "Step 6: TH reads the Schedules attribute from the DUT" - PICS: TSTAT.S.F07 && TSTAT.S.A0051 - command: "readAttribute" - attribute: "Schedules" - response: - constraints: - type: list diff --git a/src/app/tests/suites/certification/ci-pics-values b/src/app/tests/suites/certification/ci-pics-values index 1f4f1f66e9..a2d2df1e17 100644 --- a/src/app/tests/suites/certification/ci-pics-values +++ b/src/app/tests/suites/certification/ci-pics-values @@ -1988,8 +1988,13 @@ TSTAT.S.A0045=0 TSTAT.S.A0046=0 TSTAT.S.A0047=0 TSTAT.S.A0048=1 +TSTAT.S.A0049=0 TSTAT.S.A004a=1 +TSTAT.S.A004b=0 +TSTAT.S.A004c=0 +TSTAT.S.A004d=0 TSTAT.S.A004e=1 +TSTAT.S.A004f=0 TSTAT.S.A0050=1 TSTAT.S.A0051=0 TSTAT.S.A0052=0 diff --git a/src/python_testing/TC_TSTAT_4_2.py b/src/python_testing/TC_TSTAT_4_2.py index 1cdc54923e..0e23096ad7 100644 --- a/src/python_testing/TC_TSTAT_4_2.py +++ b/src/python_testing/TC_TSTAT_4_2.py @@ -203,7 +203,7 @@ async def send_set_active_preset_handle_request_command(self, def desc_TC_TSTAT_4_2(self) -> str: """Returns a description of this test""" - return "3.2.4 [TC-TSTAT-4-2] Preset write and command attributes test case with server as DUT" + return "3.2.4 [TC-TSTAT-4-2] Test cases to read/write attributes and invoke commands for Preset feature with server as DUT" def pics_TC_TSTAT_4_2(self): """ This function returns a list of PICS for this test case that must be True for the test to be run""" From a2d94d2b5a16c50f3aadd4240b96fd437777a5e2 Mon Sep 17 00:00:00 2001 From: Yufeng Wang Date: Fri, 7 Feb 2025 10:29:55 -0800 Subject: [PATCH 29/39] Optimize flash cost for optional command in wifi diagnostic cluster (#37283) * Optimize flash cost for optional command in wifi diagnostic cluster * Restyled by whitespace --------- Co-authored-by: Restyled.io --- .../wifi-network-diagnostics-server.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/app/clusters/wifi-network-diagnostics-server/wifi-network-diagnostics-server.cpp b/src/app/clusters/wifi-network-diagnostics-server/wifi-network-diagnostics-server.cpp index 6c4b0a4cf6..0c4b86c9ef 100644 --- a/src/app/clusters/wifi-network-diagnostics-server/wifi-network-diagnostics-server.cpp +++ b/src/app/clusters/wifi-network-diagnostics-server/wifi-network-diagnostics-server.cpp @@ -66,7 +66,9 @@ class WiFiDiagosticsGlobalInstance : public AttributeAccessInterface, public Com void InvokeCommand(HandlerContext & ctx) override; +#ifdef WI_FI_NETWORK_DIAGNOSTICS_ENABLE_RESET_COUNTS_CMD void HandleResetCounts(HandlerContext & ctx, const Commands::ResetCounts::DecodableType & commandData); +#endif DiagnosticDataProvider & mDiagnosticProvider; }; @@ -254,18 +256,22 @@ void WiFiDiagosticsGlobalInstance::InvokeCommand(HandlerContext & handlerContext { switch (handlerContext.mRequestPath.mCommandId) { +#ifdef WI_FI_NETWORK_DIAGNOSTICS_ENABLE_RESET_COUNTS_CMD case Commands::ResetCounts::Id: CommandHandlerInterface::HandleCommand( handlerContext, [this](HandlerContext & ctx, const auto & commandData) { HandleResetCounts(ctx, commandData); }); break; +#endif } } +#ifdef WI_FI_NETWORK_DIAGNOSTICS_ENABLE_RESET_COUNTS_CMD void WiFiDiagosticsGlobalInstance::HandleResetCounts(HandlerContext & ctx, const Commands::ResetCounts::DecodableType & commandData) { mDiagnosticProvider.ResetWiFiNetworkDiagnosticsCounts(); ctx.mCommandHandler.AddStatus(ctx.mRequestPath, Protocols::InteractionModel::Status::Success); } +#endif WiFiDiagosticsGlobalInstance gWiFiDiagosticsInstance(DeviceLayer::GetDiagnosticDataProvider()); From 372345e0a94140f202500fe152d4188261759556 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Fri, 7 Feb 2025 14:40:34 -0500 Subject: [PATCH 30/39] Don't log kNone events in BdxTransferDiagnosticLog::HandleTransferSessionOutput. (#37458) We get a lot of them because of the polling setup, and all they mean is "we have not gotten the next thing from the other side yet". --- src/protocols/bdx/BdxTransferDiagnosticLog.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/protocols/bdx/BdxTransferDiagnosticLog.cpp b/src/protocols/bdx/BdxTransferDiagnosticLog.cpp index 4804a01c57..19de6c5ff7 100644 --- a/src/protocols/bdx/BdxTransferDiagnosticLog.cpp +++ b/src/protocols/bdx/BdxTransferDiagnosticLog.cpp @@ -42,6 +42,16 @@ void BdxTransferDiagnosticLog::HandleTransferSessionOutput(TransferSession::Outp { assertChipStackLockedByCurrentThread(); + if (event.EventType == TransferSession::OutputEventType::kNone) + { + // Because we are polling for output every 50ms on our transfer session, + // we will get a lot of kNone events coming through here: one for every + // time we poll but the other side has not sent anything new yet. Just + // ignore those here, for now, and make sure not to log them, because + // that bloats the logs pretty quickly. + return; + } + ChipLogDetail(BDX, "Got an event %s", event.ToString(event.EventType)); switch (event.EventType) @@ -71,7 +81,7 @@ void BdxTransferDiagnosticLog::HandleTransferSessionOutput(TransferSession::Outp } break; case TransferSession::OutputEventType::kAckEOFReceived: - case TransferSession::OutputEventType::kNone: + // case TransferSession::OutputEventType::kNone: handled above. case TransferSession::OutputEventType::kQueryWithSkipReceived: case TransferSession::OutputEventType::kQueryReceived: case TransferSession::OutputEventType::kAckReceived: From 333e921e02ae1e143a927540d6d30c6ebd68ecb1 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Fri, 7 Feb 2025 14:40:44 -0500 Subject: [PATCH 31/39] Fix incorrect comment in TLVWriter. (#37459) --- src/lib/core/TLVWriter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/core/TLVWriter.cpp b/src/lib/core/TLVWriter.cpp index 666965b22e..36487783bc 100644 --- a/src/lib/core/TLVWriter.cpp +++ b/src/lib/core/TLVWriter.cpp @@ -332,7 +332,7 @@ CHIP_ERROR TLVWriter::PutString(Tag tag, const char * buf, uint32_t len) { return CHIP_ERROR_INVALID_TLV_CHAR_STRING; } -#endif // CHIP_CONFIG_TLV_VALIDATE_CHAR_STRING_ON_READ +#endif // CHIP_CONFIG_TLV_VALIDATE_CHAR_STRING_ON_WRITE return WriteElementWithData(kTLVType_UTF8String, tag, reinterpret_cast(buf), len); } From 841df09c3a7ed333579188c7973fc3a255070ecd Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Fri, 7 Feb 2025 14:51:17 -0500 Subject: [PATCH 32/39] Fix comments and naming for Darwin invoke responses validation. (#37460) Some typos crept in, and the function argument name was sub-optimal. --- src/darwin/Framework/CHIP/MTRDeviceDataValidation.h | 8 ++++---- src/darwin/Framework/CHIP/MTRDeviceDataValidation.mm | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/darwin/Framework/CHIP/MTRDeviceDataValidation.h b/src/darwin/Framework/CHIP/MTRDeviceDataValidation.h index 72ee6f4679..9e48e3a9fc 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceDataValidation.h +++ b/src/darwin/Framework/CHIP/MTRDeviceDataValidation.h @@ -39,9 +39,9 @@ MTR_EXTERN MTR_TESTABLE BOOL MTREventReportIsWellFormed(NSArray * response); -// Returns whether the provided invoke reponses actually has the right sorts of -// objects in the right places. This differes from -// MTRInvokeResponseIsWellFormed in not enforcing that there is only one response. -MTR_EXTERN MTR_TESTABLE BOOL MTRInvokeResponsesAreWellFormed(NSArray * response); +// Returns whether the provided invoke responses actually have the right sorts of objects in the +// right places. This differs from MTRInvokeResponseIsWellFormed in not enforcing that there is +// only one response. +MTR_EXTERN MTR_TESTABLE BOOL MTRInvokeResponsesAreWellFormed(NSArray * responses); NS_ASSUME_NONNULL_END diff --git a/src/darwin/Framework/CHIP/MTRDeviceDataValidation.mm b/src/darwin/Framework/CHIP/MTRDeviceDataValidation.mm index ba71a80717..d3f1a45a42 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceDataValidation.mm +++ b/src/darwin/Framework/CHIP/MTRDeviceDataValidation.mm @@ -178,14 +178,14 @@ BOOL MTRInvokeResponseIsWellFormed(NSArray * r return YES; } -BOOL MTRInvokeResponsesAreWellFormed(NSArray * response) +BOOL MTRInvokeResponsesAreWellFormed(NSArray * responses) { - if (!MTR_SAFE_CAST(response, NSArray)) { - MTR_LOG_ERROR("Invoke response is not an array: %@", response); + if (!MTR_SAFE_CAST(responses, NSArray)) { + MTR_LOG_ERROR("Invoke responses are not an array: %@", responses); return NO; } - for (MTRDeviceResponseValueDictionary responseValue in response) { + for (MTRDeviceResponseValueDictionary responseValue in responses) { // Each entry must be a dictionary that has MTRCommandPathKey. if (!MTR_SAFE_CAST(responseValue, NSDictionary) || !MTR_SAFE_CAST(responseValue[MTRCommandPathKey], MTRCommandPath)) { From b6da5d52029c3cfad4b966e6eb33590f61b6fdec Mon Sep 17 00:00:00 2001 From: Ashwini <98016634+Ashwinigrl@users.noreply.github.com> Date: Sat, 8 Feb 2025 02:07:27 +0530 Subject: [PATCH 33/39] Updated TC-DD-1.10 YAML script with more detailed descriptions for test steps 1 and 2 (#37424) * Updated TC-DD-1.10 YAML script with more detailed descriptions for test step 2 and 3 * Restyled by whitespace * Updated the TC-DD-1.10 Yaml script with missing details * Restyled by whitespace * Restyled by prettier-yaml --------- Co-authored-by: Restyled.io --- .../suites/certification/Test_TC_DD_1_10.yaml | 43 +++++++++++-------- 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/src/app/tests/suites/certification/Test_TC_DD_1_10.yaml b/src/app/tests/suites/certification/Test_TC_DD_1_10.yaml index 49fec00be2..3fee1dff42 100644 --- a/src/app/tests/suites/certification/Test_TC_DD_1_10.yaml +++ b/src/app/tests/suites/certification/Test_TC_DD_1_10.yaml @@ -61,26 +61,33 @@ tests: "Step 1: Power up the TH Device and put the TH Device in commissioning mode" verification: | - 1. Launch TH that has NFC tag - ./chip-all-clusters-app - ... - [1646286638.375844][11651:11651] CHIP:DL: Device Configuration: - [1646286638.375960][11651:11651] CHIP:DL: Serial Number: TEST_SN - [1646286638.376016][11651:11651] CHIP:DL: Vendor Id: 65521 (0xFFF1) - [1646286638.376066][11651:11651] CHIP:DL: Product Id: 32769 (0x8001) - [1646286638.376153][11651:11651] CHIP:DL: Hardware Version: 0 - [1646286638.377458][11651:11651] CHIP:DL: Setup Pin Code: 20202021 - [1646286638.377541][11651:11651] CHIP:DL: Setup Discriminator: 3840 (0xF00) - [1646286638.377611][11651:11651] CHIP:DL: Manufacturing Date: (not set) - [1646286638.377664][11651:11651] CHIP:DL: Device Type: 65535 (0xFFFF) - [1646286638.377771][11651:11651] CHIP:SVR: SetupQRCode: [MT:-24J042C00KA0648G00] - [1646286638.377865][11651:11651] CHIP:SVR: Copy/paste the below URL in a browser to see the QR Code: - [1646286638.377915][11651:11651] CHIP:SVR: https://dhrishi.github.io/connectedhomeip/qrcode.html?data=MT%3A-24J042C00KA0648G00 - [1646286638.377986][11651:11651] CHIP:SVR: Manual pairing code: [34970112332] - [1646286638.378089][11651:11651] CHIP:SVR: Long manual pairing code: [749701123365521327694] + + Power on the TH Device with NFC tag, put it in Commissioning mode, and verify that TH is in a state to be commissioned by the DUT. + + I: 355 [DL]Device Configuration: + I: 358 [DL] Serial Number: 11223344556677889900 + I: 362 [DL] Vendor Id: 65521 (0xFFF1) + I: 366 [DL] Product Id: 32769 (0x8001) + I: 369 [DL] Product Name: not-specified + I: 373 [DL] Hardware Version: 0 + I: 377 [DL] Setup Pin Code (0 for UNKNOWN/ERROR): 20202021 + I: 382 [DL] Setup Discriminator (0xFFFF for UNKNOWN/ERROR): 3840 (0xF00) + I: 389 [DL] Manufacturing Date: (not set) + I: 393 [DL] Device Type: 65535 (0xFFFF) + I: 397 [SVR]SetupQRCode: [MT:-24J042C00KA0648G00] + I: 401 [SVR]Copy/paste the below URL in a browser to see the QR Code: + I: 408 [SVR]https://project-chip.github.io/connectedhomeip/qrcode.html?data=MT%3A-24J042C00KA0648G00 + I: 417 [SVR]Manual pairing code: [34970112332] + I: 422 [DL]CHIP task running + I: 426 [DL]CHIPoBLE advertising started + I: 430 [SVR]Cannot load binding table: a0 + I: 435 [DL]NFC Tag emulation started disabled: true - label: "Step 2: Bring the DUT close to the NFC tag for the TH Device" verification: | - Vendor specific field testcase as chip-all-clusters-app does not have an NFC tag to scan + 1. Bring and hold the DUT close to the NFC tag on the TH Device. + 2. Check whether the DUT can read the NFC tag. + 3. If the DUT can read the NFC tag, it should retrieve the information needed for onboarding. + 4. Verify that the DUT can successfully read and decode the NFC tag’s onboarding payload such as the setup code, device details and use the retrieved information to onboard the TH device onto the Matter network. disabled: true From 4c1a0c5672ec8a8660518c0474fbea7b2a4b50eb Mon Sep 17 00:00:00 2001 From: shripad621git <79364691+shripad621git@users.noreply.github.com> Date: Sat, 8 Feb 2025 02:15:49 +0530 Subject: [PATCH 34/39] [ESP32] Fixed the bluedroid build issue in ESP32. (#34133) - Fixed the build issue due to missing bits in bluedroid BLEManagerImpl. - Added extended ble advertising support. --- .../ESP32/bluedroid/BLEManagerImpl.cpp | 131 +++++++++++++++--- 1 file changed, 113 insertions(+), 18 deletions(-) diff --git a/src/platform/ESP32/bluedroid/BLEManagerImpl.cpp b/src/platform/ESP32/bluedroid/BLEManagerImpl.cpp index f542af93b6..3d22e5f9f3 100644 --- a/src/platform/ESP32/bluedroid/BLEManagerImpl.cpp +++ b/src/platform/ESP32/bluedroid/BLEManagerImpl.cpp @@ -147,7 +147,6 @@ const uint16_t CHIPoBLEGATTAttrCount = sizeof(CHIPoBLEGATTAttrs) / sizeof(CHIPoB ChipDeviceScanner & mDeviceScanner = Internal::ChipDeviceScanner::GetInstance(); #endif BLEManagerImpl BLEManagerImpl::sInstance; -constexpr System::Clock::Timeout BLEManagerImpl::kFastAdvertiseTimeout; #ifdef CONFIG_ENABLE_ESP32_BLE_CONTROLLER static esp_gattc_char_elem_t * char_elem_result = NULL; static esp_gattc_descr_elem_t * descr_elem_result = NULL; @@ -228,6 +227,23 @@ CHIP_ERROR BLEManagerImpl::_Init() return err; } +void BLEManagerImpl::_Shutdown() +{ + CancelBleAdvTimeoutTimer(); + + BleLayer::Shutdown(); + mServiceMode = ConnectivityManager::kCHIPoBLEServiceMode_Disabled; + + // selectively setting kGATTServiceStarted flag, in order to notify the state machine to stop the CHIPoBLE gatt service + mFlags.ClearAll().Set(Flags::kGATTServiceStarted); + +#ifdef CONFIG_ENABLE_ESP32_BLE_CONTROLLER + OnChipBleConnectReceived = nullptr; +#endif // CONFIG_ENABLE_ESP32_BLE_CONTROLLER + + PlatformMgr().ScheduleWork(DriveBLEState, 0); +} + CHIP_ERROR BLEManagerImpl::_SetAdvertisingEnabled(bool val) { CHIP_ERROR err = CHIP_NO_ERROR; @@ -236,8 +252,7 @@ CHIP_ERROR BLEManagerImpl::_SetAdvertisingEnabled(bool val) if (val) { - mAdvertiseStartTime = System::SystemClock().GetMonotonicTimestamp(); - ReturnErrorOnFailure(DeviceLayer::SystemLayer().StartTimer(kFastAdvertiseTimeout, HandleFastAdvertisementTimer, this)); + StartBleAdvTimeoutTimer(CHIP_DEVICE_CONFIG_BLE_ADVERTISING_INTERVAL_CHANGE_TIME); } mFlags.Set(Flags::kFastAdvertisingEnabled, val); mFlags.Set(Flags::kAdvertisingRefreshNeeded, 1); @@ -247,21 +262,29 @@ CHIP_ERROR BLEManagerImpl::_SetAdvertisingEnabled(bool val) return err; } -void BLEManagerImpl::HandleFastAdvertisementTimer(System::Layer * systemLayer, void * context) -{ - static_cast(context)->HandleFastAdvertisementTimer(); -} - -void BLEManagerImpl::HandleFastAdvertisementTimer() +void BLEManagerImpl::BleAdvTimeoutHandler(System::Layer *, void *) { - System::Clock::Timestamp currentTimestamp = System::SystemClock().GetMonotonicTimestamp(); - - if (currentTimestamp - mAdvertiseStartTime >= kFastAdvertiseTimeout) + if (BLEMgrImpl().mFlags.Has(Flags::kFastAdvertisingEnabled)) + { + ChipLogProgress(DeviceLayer, "bleAdv Timeout : Start slow advertisement"); + BLEMgrImpl().mFlags.Set(Flags::kFastAdvertisingEnabled, 0); + BLEMgrImpl().mFlags.Set(Flags::kAdvertisingRefreshNeeded, 1); +#if CHIP_DEVICE_CONFIG_EXT_ADVERTISING + BLEMgrImpl().mFlags.Clear(Flags::kExtAdvertisingEnabled); + BLEMgrImpl().StartBleAdvTimeoutTimer(CHIP_DEVICE_CONFIG_BLE_EXT_ADVERTISING_INTERVAL_CHANGE_TIME_MS); +#endif + } +#if CHIP_DEVICE_CONFIG_EXT_ADVERTISING + else { - mFlags.Clear(Flags::kFastAdvertisingEnabled); - mFlags.Set(Flags::kAdvertisingRefreshNeeded); - PlatformMgr().ScheduleWork(DriveBLEState, 0); + ChipLogProgress(DeviceLayer, "bleAdv Timeout : Start extended advertisement"); + BLEMgrImpl().mFlags.Set(Flags::kAdvertising); + BLEMgrImpl().mFlags.Set(Flags::kExtAdvertisingEnabled); + BLEMgr().SetAdvertisingMode(BLEAdvertisingMode::kSlowAdvertising); + BLEMgrImpl().mFlags.Set(Flags::kAdvertisingRefreshNeeded, 1); } +#endif + PlatformMgr().ScheduleWork(DriveBLEState, 0); } CHIP_ERROR BLEManagerImpl::_SetAdvertisingMode(BLEAdvertisingMode mode) @@ -843,8 +866,8 @@ CHIP_ERROR BLEManagerImpl::SendIndication(BLE_CONNECTION_OBJECT conId, const Chi #endif // Set param need_confirm as false will send notification, otherwise indication. - err = MapBLEError( - esp_ble_gatts_send_indicate(mAppIf, conId, mTXCharAttrHandle, data->DataLength(), data->Start(), true /* need_confirm */)); + err = MapBLEError(esp_ble_gatts_send_indicate(mAppIf, conId, mTXCharAttrHandle, static_cast(data->DataLength()), + data->Start(), true /* need_confirm */)); if (err != CHIP_NO_ERROR) { ChipLogError(DeviceLayer, "esp_ble_gatts_send_indicate() failed: %s", ErrorStr(err)); @@ -907,6 +930,20 @@ CHIP_ERROR BLEManagerImpl::MapBLEError(int bleErr) } } +void BLEManagerImpl::CancelBleAdvTimeoutTimer(void) +{ + SystemLayer().CancelTimer(BleAdvTimeoutHandler, nullptr); +} + +void BLEManagerImpl::StartBleAdvTimeoutTimer(uint32_t aTimeoutInMs) +{ + CHIP_ERROR err = SystemLayer().StartTimer(System::Clock::Milliseconds32(aTimeoutInMs), BleAdvTimeoutHandler, nullptr); + if ((err != CHIP_NO_ERROR)) + { + ChipLogError(DeviceLayer, "Failed to start BledAdv timeout timer"); + } +} + void BLEManagerImpl::DriveBLEState(void) { CHIP_ERROR err = CHIP_NO_ERROR; @@ -1030,7 +1067,8 @@ void BLEManagerImpl::DriveBLEState(void) ExitNow(); } - mFlags.Set(Flags::kControlOpInProgress); + DeinitESPBleLayer(); + mFlags.ClearAll(); ExitNow(); } @@ -1133,6 +1171,23 @@ CHIP_ERROR BLEManagerImpl::InitESPBleLayer(void) return err; } +esp_err_t bluedroid_set_random_address() +{ + esp_bd_addr_t rand_addr; + + esp_fill_random(rand_addr, sizeof(esp_bd_addr_t)); + rand_addr[0] = (rand_addr[0] & 0x3F) | 0xC0; + + esp_err_t ret = esp_ble_gap_set_rand_addr(rand_addr); + if (ret != ESP_OK) + { + ChipLogError(DeviceLayer, "Failed to set random address: %s", esp_err_to_name(ret)); + return ret; + } + + return ESP_OK; +} + CHIP_ERROR BLEManagerImpl::ConfigureAdvertisingData(void) { CHIP_ERROR err; @@ -1158,6 +1213,27 @@ CHIP_ERROR BLEManagerImpl::ConfigureAdvertisingData(void) ExitNow(); } +#if CHIP_DEVICE_CONFIG_EXT_ADVERTISING + // Check for extended advertisement interval and redact VID/PID if past the initial period. + if (mFlags.Has(Flags::kExtAdvertisingEnabled)) + { + deviceIdInfo.SetVendorId(0); + deviceIdInfo.SetProductId(0); + deviceIdInfo.SetExtendedAnnouncementFlag(true); + } +#endif + +#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING + if (!mFlags.Has(Flags::kExtAdvertisingEnabled)) + { + deviceIdInfo.SetAdditionalDataFlag(true); + } + else + { + deviceIdInfo.SetAdditionalDataFlag(false); + } +#endif + memset(advData, 0, sizeof(advData)); advData[index++] = 0x02; // length advData[index++] = CHIP_ADV_DATA_TYPE_FLAGS; // AD type : flags @@ -1187,12 +1263,16 @@ CHIP_ERROR BLEManagerImpl::ConfigureAdvertisingData(void) ExitNow(); } + bluedroid_set_random_address(); mFlags.Set(Flags::kControlOpInProgress); exit: return err; } +// TODO(#36919): Fix the Bluedroid ShutDown flow for ESP32. +void BLEManagerImpl::DeinitESPBleLayer() {} + CHIP_ERROR BLEManagerImpl::StartAdvertising(void) { CHIP_ERROR err; @@ -1223,8 +1303,23 @@ CHIP_ERROR BLEManagerImpl::StartAdvertising(void) } else { +#if CHIP_DEVICE_CONFIG_EXT_ADVERTISING + if (!mFlags.Has(Flags::kExtAdvertisingEnabled)) + { + advertParams.adv_int_min = CHIP_DEVICE_CONFIG_BLE_SLOW_ADVERTISING_INTERVAL_MIN; + advertParams.adv_int_max = CHIP_DEVICE_CONFIG_BLE_SLOW_ADVERTISING_INTERVAL_MAX; + } + else + { + advertParams.adv_int_min = CHIP_DEVICE_CONFIG_BLE_EXT_ADVERTISING_INTERVAL_MIN; + advertParams.adv_int_max = CHIP_DEVICE_CONFIG_BLE_EXT_ADVERTISING_INTERVAL_MAX; + } +#else + advertParams.adv_int_min = CHIP_DEVICE_CONFIG_BLE_SLOW_ADVERTISING_INTERVAL_MIN; advertParams.adv_int_max = CHIP_DEVICE_CONFIG_BLE_SLOW_ADVERTISING_INTERVAL_MAX; + +#endif } ChipLogProgress(DeviceLayer, "Configuring CHIPoBLE advertising (interval %" PRIu32 " ms, %sconnectable, device name %s)", From eea382e1b4759de128a387a9268d45d533837e5f Mon Sep 17 00:00:00 2001 From: Terence Hampson Date: Fri, 7 Feb 2025 17:13:45 -0500 Subject: [PATCH 35/39] Update TCUpdateDeadline to be nullable to match spec (#37438) * Update TCUpdateDeadline to be nullable to match spec * Empty-Commit * Add xml file * re-add option=true * regen --- .../air-purifier-app.matter | 2 +- .../air-quality-sensor-app.matter | 2 +- .../all-clusters-app.matter | 2 +- .../all-clusters-minimal-app.matter | 2 +- .../bridge-common/bridge-app.matter | 2 +- ...p_rootnode_dimmablelight_bCwGYSDpoe.matter | 2 +- .../rootnode_airpurifier_73a6fe2651.matter | 2 +- ...umiditysensor_thermostat_56de3d5f45.matter | 2 +- ...ootnode_airqualitysensor_e63187f6c9.matter | 2 +- ...ootnode_basicvideoplayer_0ff86e943b.matter | 2 +- ...de_colortemperaturelight_hbUnzYVeyn.matter | 2 +- .../rootnode_contactsensor_27f76aeaf5.matter | 2 +- .../rootnode_contactsensor_lFAGG1bfRO.matter | 2 +- ...ualitysensor_powersource_367e7cea91.matter | 2 +- .../rootnode_dimmablelight_bCwGYSDpoe.matter | 2 +- ...tnode_dimmablepluginunit_f8a9a0b9d4.matter | 2 +- .../rootnode_dishwasher_cc105034fe.matter | 2 +- .../rootnode_doorlock_aNKYAreMXE.matter | 2 +- ...tnode_extendedcolorlight_8lcaaYJVAa.matter | 2 +- .../devices/rootnode_fan_7N2TobIlOX.matter | 2 +- .../rootnode_flowsensor_1zVxHedlaV.matter | 2 +- .../rootnode_genericswitch_2dfff6e516.matter | 2 +- .../rootnode_genericswitch_9866e35d0b.matter | 2 +- ...tnode_heatingcoolingunit_ncdGai1E5a.matter | 2 +- .../rootnode_heatpump_87ivjRAECh.matter | 2 +- .../rootnode_humiditysensor_Xyj4gda6Hb.matter | 2 +- .../rootnode_laundrydryer_01796fe396.matter | 2 +- .../rootnode_laundrywasher_fb10d238c8.matter | 2 +- .../rootnode_lightsensor_lZQycTFcJK.matter | 2 +- ...rootnode_occupancysensor_iHyVgifZuo.matter | 2 +- .../rootnode_onofflight_bbs1b7IaOV.matter | 2 +- .../rootnode_onofflight_samplemei.matter | 2 +- ...ootnode_onofflightswitch_FsPlMr090Q.matter | 2 +- ...rootnode_onoffpluginunit_Wtf8ss5EBY.matter | 2 +- .../rootnode_pressuresensor_s0qC9wLH4k.matter | 2 +- .../devices/rootnode_pump_5f904818cc.matter | 2 +- .../devices/rootnode_pump_a811bb33a0.matter | 2 +- ...eraturecontrolledcabinet_ffdb696680.matter | 2 +- ...ode_roboticvacuumcleaner_1807ff0c49.matter | 2 +- ...tnode_roomairconditioner_9cf3607804.matter | 2 +- .../rootnode_smokecoalarm_686fe0dcb8.matter | 2 +- .../rootnode_speaker_RpzeXdimqA.matter | 2 +- ...otnode_temperaturesensor_Qy1zkNW7c3.matter | 2 +- .../rootnode_thermostat_bm3fb8dhYi.matter | 2 +- ...otnode_waterleakdetector_0b067acfa3.matter | 2 +- .../rootnode_watervalve_6bb39f1f67.matter | 2 +- .../rootnode_windowcovering_RLCxaGi9Yx.matter | 2 +- .../data_model/contact-sensor-app.matter | 2 +- .../contact-sensor-app.matter | 2 +- .../nxp/zap-lit/contact-sensor-app.matter | 2 +- .../nxp/zap-sit/contact-sensor-app.matter | 2 +- .../dishwasher-common/dishwasher-app.matter | 2 +- .../data_model/dishwasher-thread-app.matter | 2 +- .../data_model/dishwasher-wifi-app.matter | 2 +- .../energy-management-app.matter | 2 +- .../fabric-bridge-app.matter | 2 +- .../fabric-sync/bridge/fabric-bridge.matter | 2 +- .../nxp/zap/laundry-washer-app.matter | 2 +- .../icd-lit-light-switch-app.matter | 2 +- .../light-switch-app.matter | 2 +- .../light-switch-app/qpg/zap/switch.matter | 2 +- .../lighting-common/lighting-app.matter | 2 +- .../data_model/lighting-app-ethernet.matter | 2 +- .../data_model/lighting-app-thread.matter | 2 +- .../data_model/lighting-app-wifi.matter | 2 +- .../lighting-common/lighting-app.matter | 2 +- .../nxp/zap/lighting-on-off.matter | 2 +- examples/lighting-app/qpg/zap/light.matter | 2 +- .../data_model/lighting-thread-app.matter | 2 +- .../data_model/lighting-wifi-app.matter | 2 +- .../lit-icd-common/lit-icd-server-app.matter | 2 +- examples/lock-app/lock-common/lock-app.matter | 2 +- examples/lock-app/nxp/zap/lock-app.matter | 2 +- examples/lock-app/qpg/zap/lock.matter | 2 +- .../silabs/data_model/lock-app.matter | 2 +- .../log-source-common/log-source-app.matter | 2 +- .../microwave-oven-app.matter | 2 +- .../network-manager-app.matter | 2 +- .../ota-provider-app.matter | 2 +- .../ota-requestor-app.matter | 2 +- .../placeholder/linux/apps/app1/config.matter | 4 +- .../placeholder/linux/apps/app2/config.matter | 4 +- examples/pump-app/pump-common/pump-app.matter | 2 +- .../silabs/data_model/pump-thread-app.matter | 2 +- .../silabs/data_model/pump-wifi-app.matter | 2 +- .../pump-controller-app.matter | 2 +- .../refrigerator-app.matter | 2 +- .../data_model/refrigerator-thread-app.matter | 2 +- .../data_model/refrigerator-wifi-app.matter | 2 +- examples/rvc-app/rvc-common/rvc-app.matter | 2 +- .../smoke-co-alarm-app.matter | 2 +- .../temperature-measurement.matter | 2 +- .../terms-and-conditions-app.matter | 2 +- .../nxp/zap/thermostat_matter_br.matter | 2 +- .../nxp/zap/thermostat_matter_thread.matter | 2 +- .../nxp/zap/thermostat_matter_wifi.matter | 2 +- .../qpg/zap/thermostaticRadiatorValve.matter | 2 +- .../thermostat-common/thermostat.matter | 2 +- .../thread-br-common/thread-br-app.matter | 2 +- examples/tv-app/tv-common/tv-app.matter | 4 +- .../tv-casting-common/tv-casting-app.matter | 2 +- .../virtual-device-app.matter | 2 +- .../water-leak-detector-app.matter | 2 +- examples/window-app/common/window-app.matter | 2 +- .../chip/general-commissioning-cluster.xml | 2 +- .../data_model/controller-clusters.matter | 2 +- .../chip/devicecontroller/ChipClusters.java | 12 ++-- .../devicecontroller/ClusterInfoMapping.java | 21 +++++++ .../devicecontroller/ClusterReadMapping.java | 4 +- .../clusters/GeneralCommissioningCluster.kt | 40 ++++++++++---- .../CHIPAttributeTLVValueDecoder.cpp | 17 ++++-- .../python/chip/clusters/Objects.py | 8 +-- .../MTRAttributeTLVValueDecoder.mm | 8 ++- .../zap-generated/attributes/Accessors.cpp | 55 +++++++++++++++++-- .../zap-generated/attributes/Accessors.h | 7 ++- .../zap-generated/cluster-objects.h | 8 +-- .../zap-generated/cluster/Commands.h | 5 +- .../cluster/logging/DataModelLogger.cpp | 2 +- 118 files changed, 255 insertions(+), 150 deletions(-) diff --git a/examples/air-purifier-app/air-purifier-common/air-purifier-app.matter b/examples/air-purifier-app/air-purifier-common/air-purifier-app.matter index be9b08eecf..89c64d93c5 100644 --- a/examples/air-purifier-app/air-purifier-common/air-purifier-app.matter +++ b/examples/air-purifier-app/air-purifier-common/air-purifier-app.matter @@ -739,7 +739,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; 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 3fac5bbaea..aad9aaf08a 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 @@ -739,7 +739,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; 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 be6f4c0622..72bf20161f 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 @@ -1642,7 +1642,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; 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 e7c61c1c30..e7187a5e5f 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 @@ -1557,7 +1557,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/bridge-app/bridge-common/bridge-app.matter b/examples/bridge-app/bridge-common/bridge-app.matter index a17e26628c..f33ce16ab5 100644 --- a/examples/bridge-app/bridge-common/bridge-app.matter +++ b/examples/bridge-app/bridge-common/bridge-app.matter @@ -1046,7 +1046,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/chef/devices/noip_rootnode_dimmablelight_bCwGYSDpoe.matter b/examples/chef/devices/noip_rootnode_dimmablelight_bCwGYSDpoe.matter index 931784e091..3708f5f16d 100644 --- a/examples/chef/devices/noip_rootnode_dimmablelight_bCwGYSDpoe.matter +++ b/examples/chef/devices/noip_rootnode_dimmablelight_bCwGYSDpoe.matter @@ -1034,7 +1034,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/chef/devices/rootnode_airpurifier_73a6fe2651.matter b/examples/chef/devices/rootnode_airpurifier_73a6fe2651.matter index d3e3b7b2d5..e0e14bea72 100644 --- a/examples/chef/devices/rootnode_airpurifier_73a6fe2651.matter +++ b/examples/chef/devices/rootnode_airpurifier_73a6fe2651.matter @@ -811,7 +811,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/chef/devices/rootnode_airpurifier_airqualitysensor_temperaturesensor_humiditysensor_thermostat_56de3d5f45.matter b/examples/chef/devices/rootnode_airpurifier_airqualitysensor_temperaturesensor_humiditysensor_thermostat_56de3d5f45.matter index dfa25e487b..d97bc10741 100644 --- a/examples/chef/devices/rootnode_airpurifier_airqualitysensor_temperaturesensor_humiditysensor_thermostat_56de3d5f45.matter +++ b/examples/chef/devices/rootnode_airpurifier_airqualitysensor_temperaturesensor_humiditysensor_thermostat_56de3d5f45.matter @@ -662,7 +662,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/chef/devices/rootnode_airqualitysensor_e63187f6c9.matter b/examples/chef/devices/rootnode_airqualitysensor_e63187f6c9.matter index aef07a846c..b5ead0bc93 100644 --- a/examples/chef/devices/rootnode_airqualitysensor_e63187f6c9.matter +++ b/examples/chef/devices/rootnode_airqualitysensor_e63187f6c9.matter @@ -998,7 +998,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/chef/devices/rootnode_basicvideoplayer_0ff86e943b.matter b/examples/chef/devices/rootnode_basicvideoplayer_0ff86e943b.matter index 9d1c73090d..2791456702 100644 --- a/examples/chef/devices/rootnode_basicvideoplayer_0ff86e943b.matter +++ b/examples/chef/devices/rootnode_basicvideoplayer_0ff86e943b.matter @@ -936,7 +936,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/chef/devices/rootnode_colortemperaturelight_hbUnzYVeyn.matter b/examples/chef/devices/rootnode_colortemperaturelight_hbUnzYVeyn.matter index 17b103e7d3..c6d7688cd7 100644 --- a/examples/chef/devices/rootnode_colortemperaturelight_hbUnzYVeyn.matter +++ b/examples/chef/devices/rootnode_colortemperaturelight_hbUnzYVeyn.matter @@ -1013,7 +1013,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/chef/devices/rootnode_contactsensor_27f76aeaf5.matter b/examples/chef/devices/rootnode_contactsensor_27f76aeaf5.matter index b28730a401..387d148dd4 100644 --- a/examples/chef/devices/rootnode_contactsensor_27f76aeaf5.matter +++ b/examples/chef/devices/rootnode_contactsensor_27f76aeaf5.matter @@ -998,7 +998,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/chef/devices/rootnode_contactsensor_lFAGG1bfRO.matter b/examples/chef/devices/rootnode_contactsensor_lFAGG1bfRO.matter index 4f9bdd5488..7218e30a77 100644 --- a/examples/chef/devices/rootnode_contactsensor_lFAGG1bfRO.matter +++ b/examples/chef/devices/rootnode_contactsensor_lFAGG1bfRO.matter @@ -1096,7 +1096,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/chef/devices/rootnode_contactsensor_lightsensor_occupancysensor_temperaturesensor_pressuresensor_flowsensor_humiditysensor_airqualitysensor_powersource_367e7cea91.matter b/examples/chef/devices/rootnode_contactsensor_lightsensor_occupancysensor_temperaturesensor_pressuresensor_flowsensor_humiditysensor_airqualitysensor_powersource_367e7cea91.matter index c7acde0a5c..2e8cb4fa40 100644 --- a/examples/chef/devices/rootnode_contactsensor_lightsensor_occupancysensor_temperaturesensor_pressuresensor_flowsensor_humiditysensor_airqualitysensor_powersource_367e7cea91.matter +++ b/examples/chef/devices/rootnode_contactsensor_lightsensor_occupancysensor_temperaturesensor_pressuresensor_flowsensor_humiditysensor_airqualitysensor_powersource_367e7cea91.matter @@ -882,7 +882,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/chef/devices/rootnode_dimmablelight_bCwGYSDpoe.matter b/examples/chef/devices/rootnode_dimmablelight_bCwGYSDpoe.matter index a2b13bd5ff..dc1caab13d 100644 --- a/examples/chef/devices/rootnode_dimmablelight_bCwGYSDpoe.matter +++ b/examples/chef/devices/rootnode_dimmablelight_bCwGYSDpoe.matter @@ -1034,7 +1034,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/chef/devices/rootnode_dimmablepluginunit_f8a9a0b9d4.matter b/examples/chef/devices/rootnode_dimmablepluginunit_f8a9a0b9d4.matter index b2c67e9c9a..aaa65fd7f8 100644 --- a/examples/chef/devices/rootnode_dimmablepluginunit_f8a9a0b9d4.matter +++ b/examples/chef/devices/rootnode_dimmablepluginunit_f8a9a0b9d4.matter @@ -1034,7 +1034,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/chef/devices/rootnode_dishwasher_cc105034fe.matter b/examples/chef/devices/rootnode_dishwasher_cc105034fe.matter index 9eac1825e8..ae5c731a47 100644 --- a/examples/chef/devices/rootnode_dishwasher_cc105034fe.matter +++ b/examples/chef/devices/rootnode_dishwasher_cc105034fe.matter @@ -700,7 +700,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/chef/devices/rootnode_doorlock_aNKYAreMXE.matter b/examples/chef/devices/rootnode_doorlock_aNKYAreMXE.matter index 57ebf108fc..11c9df1bdd 100644 --- a/examples/chef/devices/rootnode_doorlock_aNKYAreMXE.matter +++ b/examples/chef/devices/rootnode_doorlock_aNKYAreMXE.matter @@ -998,7 +998,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/chef/devices/rootnode_extendedcolorlight_8lcaaYJVAa.matter b/examples/chef/devices/rootnode_extendedcolorlight_8lcaaYJVAa.matter index 11c3186dcb..67fb7e1563 100644 --- a/examples/chef/devices/rootnode_extendedcolorlight_8lcaaYJVAa.matter +++ b/examples/chef/devices/rootnode_extendedcolorlight_8lcaaYJVAa.matter @@ -1034,7 +1034,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/chef/devices/rootnode_fan_7N2TobIlOX.matter b/examples/chef/devices/rootnode_fan_7N2TobIlOX.matter index 217d06a4e7..06d050dbaf 100644 --- a/examples/chef/devices/rootnode_fan_7N2TobIlOX.matter +++ b/examples/chef/devices/rootnode_fan_7N2TobIlOX.matter @@ -816,7 +816,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/chef/devices/rootnode_flowsensor_1zVxHedlaV.matter b/examples/chef/devices/rootnode_flowsensor_1zVxHedlaV.matter index 7d4b787540..be8c40cd8f 100644 --- a/examples/chef/devices/rootnode_flowsensor_1zVxHedlaV.matter +++ b/examples/chef/devices/rootnode_flowsensor_1zVxHedlaV.matter @@ -837,7 +837,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/chef/devices/rootnode_genericswitch_2dfff6e516.matter b/examples/chef/devices/rootnode_genericswitch_2dfff6e516.matter index aa8846b6c6..284c95c7da 100644 --- a/examples/chef/devices/rootnode_genericswitch_2dfff6e516.matter +++ b/examples/chef/devices/rootnode_genericswitch_2dfff6e516.matter @@ -844,7 +844,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/chef/devices/rootnode_genericswitch_9866e35d0b.matter b/examples/chef/devices/rootnode_genericswitch_9866e35d0b.matter index 5d79f67076..264e0dda4a 100644 --- a/examples/chef/devices/rootnode_genericswitch_9866e35d0b.matter +++ b/examples/chef/devices/rootnode_genericswitch_9866e35d0b.matter @@ -844,7 +844,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/chef/devices/rootnode_heatingcoolingunit_ncdGai1E5a.matter b/examples/chef/devices/rootnode_heatingcoolingunit_ncdGai1E5a.matter index 76eac769b1..74df51a353 100644 --- a/examples/chef/devices/rootnode_heatingcoolingunit_ncdGai1E5a.matter +++ b/examples/chef/devices/rootnode_heatingcoolingunit_ncdGai1E5a.matter @@ -1034,7 +1034,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/chef/devices/rootnode_heatpump_87ivjRAECh.matter b/examples/chef/devices/rootnode_heatpump_87ivjRAECh.matter index ecd48d7486..1424b6e5c6 100644 --- a/examples/chef/devices/rootnode_heatpump_87ivjRAECh.matter +++ b/examples/chef/devices/rootnode_heatpump_87ivjRAECh.matter @@ -861,7 +861,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/chef/devices/rootnode_humiditysensor_Xyj4gda6Hb.matter b/examples/chef/devices/rootnode_humiditysensor_Xyj4gda6Hb.matter index a401aed997..f9d843310c 100644 --- a/examples/chef/devices/rootnode_humiditysensor_Xyj4gda6Hb.matter +++ b/examples/chef/devices/rootnode_humiditysensor_Xyj4gda6Hb.matter @@ -837,7 +837,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/chef/devices/rootnode_laundrydryer_01796fe396.matter b/examples/chef/devices/rootnode_laundrydryer_01796fe396.matter index 7960936439..9b7d8b8d0e 100644 --- a/examples/chef/devices/rootnode_laundrydryer_01796fe396.matter +++ b/examples/chef/devices/rootnode_laundrydryer_01796fe396.matter @@ -700,7 +700,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/chef/devices/rootnode_laundrywasher_fb10d238c8.matter b/examples/chef/devices/rootnode_laundrywasher_fb10d238c8.matter index c92cf98aed..859cc006e5 100644 --- a/examples/chef/devices/rootnode_laundrywasher_fb10d238c8.matter +++ b/examples/chef/devices/rootnode_laundrywasher_fb10d238c8.matter @@ -633,7 +633,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/chef/devices/rootnode_lightsensor_lZQycTFcJK.matter b/examples/chef/devices/rootnode_lightsensor_lZQycTFcJK.matter index 167fb98e36..19df33a826 100644 --- a/examples/chef/devices/rootnode_lightsensor_lZQycTFcJK.matter +++ b/examples/chef/devices/rootnode_lightsensor_lZQycTFcJK.matter @@ -837,7 +837,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/chef/devices/rootnode_occupancysensor_iHyVgifZuo.matter b/examples/chef/devices/rootnode_occupancysensor_iHyVgifZuo.matter index 2d35dcb2f8..33430b65a5 100644 --- a/examples/chef/devices/rootnode_occupancysensor_iHyVgifZuo.matter +++ b/examples/chef/devices/rootnode_occupancysensor_iHyVgifZuo.matter @@ -837,7 +837,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/chef/devices/rootnode_onofflight_bbs1b7IaOV.matter b/examples/chef/devices/rootnode_onofflight_bbs1b7IaOV.matter index f91a4df653..8e51da93a8 100644 --- a/examples/chef/devices/rootnode_onofflight_bbs1b7IaOV.matter +++ b/examples/chef/devices/rootnode_onofflight_bbs1b7IaOV.matter @@ -1034,7 +1034,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/chef/devices/rootnode_onofflight_samplemei.matter b/examples/chef/devices/rootnode_onofflight_samplemei.matter index 174f5c1194..c9eefc528c 100644 --- a/examples/chef/devices/rootnode_onofflight_samplemei.matter +++ b/examples/chef/devices/rootnode_onofflight_samplemei.matter @@ -1034,7 +1034,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/chef/devices/rootnode_onofflightswitch_FsPlMr090Q.matter b/examples/chef/devices/rootnode_onofflightswitch_FsPlMr090Q.matter index 190a3a4edc..ec32c8fd55 100644 --- a/examples/chef/devices/rootnode_onofflightswitch_FsPlMr090Q.matter +++ b/examples/chef/devices/rootnode_onofflightswitch_FsPlMr090Q.matter @@ -909,7 +909,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/chef/devices/rootnode_onoffpluginunit_Wtf8ss5EBY.matter b/examples/chef/devices/rootnode_onoffpluginunit_Wtf8ss5EBY.matter index 4da57e8e1b..04a03a890e 100644 --- a/examples/chef/devices/rootnode_onoffpluginunit_Wtf8ss5EBY.matter +++ b/examples/chef/devices/rootnode_onoffpluginunit_Wtf8ss5EBY.matter @@ -909,7 +909,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/chef/devices/rootnode_pressuresensor_s0qC9wLH4k.matter b/examples/chef/devices/rootnode_pressuresensor_s0qC9wLH4k.matter index 3d493f9266..2fc51aa6d2 100644 --- a/examples/chef/devices/rootnode_pressuresensor_s0qC9wLH4k.matter +++ b/examples/chef/devices/rootnode_pressuresensor_s0qC9wLH4k.matter @@ -837,7 +837,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/chef/devices/rootnode_pump_5f904818cc.matter b/examples/chef/devices/rootnode_pump_5f904818cc.matter index 741dda60e3..3b84270148 100644 --- a/examples/chef/devices/rootnode_pump_5f904818cc.matter +++ b/examples/chef/devices/rootnode_pump_5f904818cc.matter @@ -683,7 +683,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/chef/devices/rootnode_pump_a811bb33a0.matter b/examples/chef/devices/rootnode_pump_a811bb33a0.matter index 50c2dd3163..02e9e66ca7 100644 --- a/examples/chef/devices/rootnode_pump_a811bb33a0.matter +++ b/examples/chef/devices/rootnode_pump_a811bb33a0.matter @@ -683,7 +683,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/chef/devices/rootnode_refrigerator_temperaturecontrolledcabinet_temperaturecontrolledcabinet_ffdb696680.matter b/examples/chef/devices/rootnode_refrigerator_temperaturecontrolledcabinet_temperaturecontrolledcabinet_ffdb696680.matter index 686d67e3fa..9bb5cc3e54 100644 --- a/examples/chef/devices/rootnode_refrigerator_temperaturecontrolledcabinet_temperaturecontrolledcabinet_ffdb696680.matter +++ b/examples/chef/devices/rootnode_refrigerator_temperaturecontrolledcabinet_temperaturecontrolledcabinet_ffdb696680.matter @@ -561,7 +561,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/chef/devices/rootnode_roboticvacuumcleaner_1807ff0c49.matter b/examples/chef/devices/rootnode_roboticvacuumcleaner_1807ff0c49.matter index 9abd9b1972..0707bf5609 100644 --- a/examples/chef/devices/rootnode_roboticvacuumcleaner_1807ff0c49.matter +++ b/examples/chef/devices/rootnode_roboticvacuumcleaner_1807ff0c49.matter @@ -921,7 +921,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/chef/devices/rootnode_roomairconditioner_9cf3607804.matter b/examples/chef/devices/rootnode_roomairconditioner_9cf3607804.matter index bb4a46da84..4beb90738f 100644 --- a/examples/chef/devices/rootnode_roomairconditioner_9cf3607804.matter +++ b/examples/chef/devices/rootnode_roomairconditioner_9cf3607804.matter @@ -734,7 +734,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/chef/devices/rootnode_smokecoalarm_686fe0dcb8.matter b/examples/chef/devices/rootnode_smokecoalarm_686fe0dcb8.matter index f64237210b..4f9b45792a 100644 --- a/examples/chef/devices/rootnode_smokecoalarm_686fe0dcb8.matter +++ b/examples/chef/devices/rootnode_smokecoalarm_686fe0dcb8.matter @@ -921,7 +921,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/chef/devices/rootnode_speaker_RpzeXdimqA.matter b/examples/chef/devices/rootnode_speaker_RpzeXdimqA.matter index ef250cb352..4a84aafc95 100644 --- a/examples/chef/devices/rootnode_speaker_RpzeXdimqA.matter +++ b/examples/chef/devices/rootnode_speaker_RpzeXdimqA.matter @@ -957,7 +957,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/chef/devices/rootnode_temperaturesensor_Qy1zkNW7c3.matter b/examples/chef/devices/rootnode_temperaturesensor_Qy1zkNW7c3.matter index e26a62dfd2..74466e8f88 100644 --- a/examples/chef/devices/rootnode_temperaturesensor_Qy1zkNW7c3.matter +++ b/examples/chef/devices/rootnode_temperaturesensor_Qy1zkNW7c3.matter @@ -837,7 +837,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/chef/devices/rootnode_thermostat_bm3fb8dhYi.matter b/examples/chef/devices/rootnode_thermostat_bm3fb8dhYi.matter index 549c98f930..0b130ba09b 100644 --- a/examples/chef/devices/rootnode_thermostat_bm3fb8dhYi.matter +++ b/examples/chef/devices/rootnode_thermostat_bm3fb8dhYi.matter @@ -898,7 +898,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/chef/devices/rootnode_waterleakdetector_0b067acfa3.matter b/examples/chef/devices/rootnode_waterleakdetector_0b067acfa3.matter index 67f17e7ab9..951bd8e49c 100644 --- a/examples/chef/devices/rootnode_waterleakdetector_0b067acfa3.matter +++ b/examples/chef/devices/rootnode_waterleakdetector_0b067acfa3.matter @@ -921,7 +921,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/chef/devices/rootnode_watervalve_6bb39f1f67.matter b/examples/chef/devices/rootnode_watervalve_6bb39f1f67.matter index 017be5921f..4fd15cc54d 100644 --- a/examples/chef/devices/rootnode_watervalve_6bb39f1f67.matter +++ b/examples/chef/devices/rootnode_watervalve_6bb39f1f67.matter @@ -861,7 +861,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/chef/devices/rootnode_windowcovering_RLCxaGi9Yx.matter b/examples/chef/devices/rootnode_windowcovering_RLCxaGi9Yx.matter index 30b58d9205..204d597491 100644 --- a/examples/chef/devices/rootnode_windowcovering_RLCxaGi9Yx.matter +++ b/examples/chef/devices/rootnode_windowcovering_RLCxaGi9Yx.matter @@ -837,7 +837,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/contact-sensor-app/bouffalolab/data_model/contact-sensor-app.matter b/examples/contact-sensor-app/bouffalolab/data_model/contact-sensor-app.matter index 26c05f5250..e746c4293e 100644 --- a/examples/contact-sensor-app/bouffalolab/data_model/contact-sensor-app.matter +++ b/examples/contact-sensor-app/bouffalolab/data_model/contact-sensor-app.matter @@ -833,7 +833,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; 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 fed65931ab..91b86c89c8 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 @@ -816,7 +816,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/contact-sensor-app/nxp/zap-lit/contact-sensor-app.matter b/examples/contact-sensor-app/nxp/zap-lit/contact-sensor-app.matter index f82918c1d1..6762116c46 100644 --- a/examples/contact-sensor-app/nxp/zap-lit/contact-sensor-app.matter +++ b/examples/contact-sensor-app/nxp/zap-lit/contact-sensor-app.matter @@ -739,7 +739,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/contact-sensor-app/nxp/zap-sit/contact-sensor-app.matter b/examples/contact-sensor-app/nxp/zap-sit/contact-sensor-app.matter index 1a9664ca9a..c882626f13 100644 --- a/examples/contact-sensor-app/nxp/zap-sit/contact-sensor-app.matter +++ b/examples/contact-sensor-app/nxp/zap-sit/contact-sensor-app.matter @@ -739,7 +739,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/dishwasher-app/dishwasher-common/dishwasher-app.matter b/examples/dishwasher-app/dishwasher-common/dishwasher-app.matter index 8e3096b7a0..69152058d5 100644 --- a/examples/dishwasher-app/dishwasher-common/dishwasher-app.matter +++ b/examples/dishwasher-app/dishwasher-common/dishwasher-app.matter @@ -709,7 +709,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/dishwasher-app/silabs/data_model/dishwasher-thread-app.matter b/examples/dishwasher-app/silabs/data_model/dishwasher-thread-app.matter index 87d6dca00e..727f8bdfbb 100644 --- a/examples/dishwasher-app/silabs/data_model/dishwasher-thread-app.matter +++ b/examples/dishwasher-app/silabs/data_model/dishwasher-thread-app.matter @@ -847,7 +847,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/dishwasher-app/silabs/data_model/dishwasher-wifi-app.matter b/examples/dishwasher-app/silabs/data_model/dishwasher-wifi-app.matter index e2daba3687..f0fbfba4be 100644 --- a/examples/dishwasher-app/silabs/data_model/dishwasher-wifi-app.matter +++ b/examples/dishwasher-app/silabs/data_model/dishwasher-wifi-app.matter @@ -847,7 +847,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/energy-management-app/energy-management-common/energy-management-app.matter b/examples/energy-management-app/energy-management-common/energy-management-app.matter index d7db07d6c9..b2ffbc07f6 100644 --- a/examples/energy-management-app/energy-management-common/energy-management-app.matter +++ b/examples/energy-management-app/energy-management-common/energy-management-app.matter @@ -931,7 +931,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/fabric-bridge-app/fabric-bridge-common/fabric-bridge-app.matter b/examples/fabric-bridge-app/fabric-bridge-common/fabric-bridge-app.matter index 2d1148bef8..53c3b3363b 100644 --- a/examples/fabric-bridge-app/fabric-bridge-common/fabric-bridge-app.matter +++ b/examples/fabric-bridge-app/fabric-bridge-common/fabric-bridge-app.matter @@ -710,7 +710,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/fabric-sync/bridge/fabric-bridge.matter b/examples/fabric-sync/bridge/fabric-bridge.matter index 2d1148bef8..53c3b3363b 100644 --- a/examples/fabric-sync/bridge/fabric-bridge.matter +++ b/examples/fabric-sync/bridge/fabric-bridge.matter @@ -710,7 +710,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/laundry-washer-app/nxp/zap/laundry-washer-app.matter b/examples/laundry-washer-app/nxp/zap/laundry-washer-app.matter index 678ca3b0f4..cd68deef8c 100644 --- a/examples/laundry-washer-app/nxp/zap/laundry-washer-app.matter +++ b/examples/laundry-washer-app/nxp/zap/laundry-washer-app.matter @@ -952,7 +952,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/light-switch-app/light-switch-common/icd-lit-light-switch-app.matter b/examples/light-switch-app/light-switch-common/icd-lit-light-switch-app.matter index 727775bfdd..502636a904 100644 --- a/examples/light-switch-app/light-switch-common/icd-lit-light-switch-app.matter +++ b/examples/light-switch-app/light-switch-common/icd-lit-light-switch-app.matter @@ -959,7 +959,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; 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 1bed030b5c..fff39097bf 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 @@ -959,7 +959,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/light-switch-app/qpg/zap/switch.matter b/examples/light-switch-app/qpg/zap/switch.matter index 8cefeeb19b..bb2cbe0082 100644 --- a/examples/light-switch-app/qpg/zap/switch.matter +++ b/examples/light-switch-app/qpg/zap/switch.matter @@ -1343,7 +1343,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/lighting-app-data-mode-no-unique-id/lighting-common/lighting-app.matter b/examples/lighting-app-data-mode-no-unique-id/lighting-common/lighting-app.matter index 4c7e31646d..ac236688cb 100644 --- a/examples/lighting-app-data-mode-no-unique-id/lighting-common/lighting-app.matter +++ b/examples/lighting-app-data-mode-no-unique-id/lighting-common/lighting-app.matter @@ -1013,7 +1013,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/lighting-app/bouffalolab/data_model/lighting-app-ethernet.matter b/examples/lighting-app/bouffalolab/data_model/lighting-app-ethernet.matter index 277e8bc07c..9c06818348 100644 --- a/examples/lighting-app/bouffalolab/data_model/lighting-app-ethernet.matter +++ b/examples/lighting-app/bouffalolab/data_model/lighting-app-ethernet.matter @@ -1013,7 +1013,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/lighting-app/bouffalolab/data_model/lighting-app-thread.matter b/examples/lighting-app/bouffalolab/data_model/lighting-app-thread.matter index e7a1fd8a68..888565b8e7 100644 --- a/examples/lighting-app/bouffalolab/data_model/lighting-app-thread.matter +++ b/examples/lighting-app/bouffalolab/data_model/lighting-app-thread.matter @@ -1013,7 +1013,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; 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 94444d34e7..13da891220 100644 --- a/examples/lighting-app/bouffalolab/data_model/lighting-app-wifi.matter +++ b/examples/lighting-app/bouffalolab/data_model/lighting-app-wifi.matter @@ -1013,7 +1013,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/lighting-app/lighting-common/lighting-app.matter b/examples/lighting-app/lighting-common/lighting-app.matter index 53f31a35e8..f83ffd158b 100644 --- a/examples/lighting-app/lighting-common/lighting-app.matter +++ b/examples/lighting-app/lighting-common/lighting-app.matter @@ -1013,7 +1013,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/lighting-app/nxp/zap/lighting-on-off.matter b/examples/lighting-app/nxp/zap/lighting-on-off.matter index a3f91b06d1..b46592166c 100644 --- a/examples/lighting-app/nxp/zap/lighting-on-off.matter +++ b/examples/lighting-app/nxp/zap/lighting-on-off.matter @@ -1013,7 +1013,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/lighting-app/qpg/zap/light.matter b/examples/lighting-app/qpg/zap/light.matter index f6ac363e2f..9e96a8eefb 100644 --- a/examples/lighting-app/qpg/zap/light.matter +++ b/examples/lighting-app/qpg/zap/light.matter @@ -1013,7 +1013,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/lighting-app/silabs/data_model/lighting-thread-app.matter b/examples/lighting-app/silabs/data_model/lighting-thread-app.matter index 7a2429dad1..2a163472d7 100644 --- a/examples/lighting-app/silabs/data_model/lighting-thread-app.matter +++ b/examples/lighting-app/silabs/data_model/lighting-thread-app.matter @@ -1013,7 +1013,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; 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 83614e8cc9..edb049d544 100644 --- a/examples/lighting-app/silabs/data_model/lighting-wifi-app.matter +++ b/examples/lighting-app/silabs/data_model/lighting-wifi-app.matter @@ -1272,7 +1272,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/lit-icd-app/lit-icd-common/lit-icd-server-app.matter b/examples/lit-icd-app/lit-icd-common/lit-icd-server-app.matter index 2fce74e7b3..abe527da52 100644 --- a/examples/lit-icd-app/lit-icd-common/lit-icd-server-app.matter +++ b/examples/lit-icd-app/lit-icd-common/lit-icd-server-app.matter @@ -765,7 +765,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/lock-app/lock-common/lock-app.matter b/examples/lock-app/lock-common/lock-app.matter index 7d26abef20..c604704bbc 100644 --- a/examples/lock-app/lock-common/lock-app.matter +++ b/examples/lock-app/lock-common/lock-app.matter @@ -1024,7 +1024,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/lock-app/nxp/zap/lock-app.matter b/examples/lock-app/nxp/zap/lock-app.matter index 7c58efd5cd..40ce2f9aa1 100644 --- a/examples/lock-app/nxp/zap/lock-app.matter +++ b/examples/lock-app/nxp/zap/lock-app.matter @@ -756,7 +756,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/lock-app/qpg/zap/lock.matter b/examples/lock-app/qpg/zap/lock.matter index b3f683515c..04ad01e698 100644 --- a/examples/lock-app/qpg/zap/lock.matter +++ b/examples/lock-app/qpg/zap/lock.matter @@ -816,7 +816,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/lock-app/silabs/data_model/lock-app.matter b/examples/lock-app/silabs/data_model/lock-app.matter index ea89439a23..d953d92f62 100644 --- a/examples/lock-app/silabs/data_model/lock-app.matter +++ b/examples/lock-app/silabs/data_model/lock-app.matter @@ -1024,7 +1024,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/log-source-app/log-source-common/log-source-app.matter b/examples/log-source-app/log-source-common/log-source-app.matter index e5f6ee1007..4fb8d8d377 100644 --- a/examples/log-source-app/log-source-common/log-source-app.matter +++ b/examples/log-source-app/log-source-common/log-source-app.matter @@ -405,7 +405,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/microwave-oven-app/microwave-oven-common/microwave-oven-app.matter b/examples/microwave-oven-app/microwave-oven-common/microwave-oven-app.matter index 57fd7ea5b7..d92b50f80e 100644 --- a/examples/microwave-oven-app/microwave-oven-common/microwave-oven-app.matter +++ b/examples/microwave-oven-app/microwave-oven-common/microwave-oven-app.matter @@ -629,7 +629,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/network-manager-app/network-manager-common/network-manager-app.matter b/examples/network-manager-app/network-manager-common/network-manager-app.matter index c802fec94c..c9fbb02c98 100644 --- a/examples/network-manager-app/network-manager-common/network-manager-app.matter +++ b/examples/network-manager-app/network-manager-common/network-manager-app.matter @@ -535,7 +535,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/ota-provider-app/ota-provider-common/ota-provider-app.matter b/examples/ota-provider-app/ota-provider-common/ota-provider-app.matter index 9619f70767..9319ae5a28 100644 --- a/examples/ota-provider-app/ota-provider-common/ota-provider-app.matter +++ b/examples/ota-provider-app/ota-provider-common/ota-provider-app.matter @@ -736,7 +736,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/ota-requestor-app/ota-requestor-common/ota-requestor-app.matter b/examples/ota-requestor-app/ota-requestor-common/ota-requestor-app.matter index 2c4f638037..141ec10b71 100644 --- a/examples/ota-requestor-app/ota-requestor-common/ota-requestor-app.matter +++ b/examples/ota-requestor-app/ota-requestor-common/ota-requestor-app.matter @@ -888,7 +888,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/placeholder/linux/apps/app1/config.matter b/examples/placeholder/linux/apps/app1/config.matter index 6bc47afef7..3d67d53aba 100644 --- a/examples/placeholder/linux/apps/app1/config.matter +++ b/examples/placeholder/linux/apps/app1/config.matter @@ -1672,7 +1672,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -1764,7 +1764,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/placeholder/linux/apps/app2/config.matter b/examples/placeholder/linux/apps/app2/config.matter index 9b116eb8ba..73581df42b 100644 --- a/examples/placeholder/linux/apps/app2/config.matter +++ b/examples/placeholder/linux/apps/app2/config.matter @@ -1629,7 +1629,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -1721,7 +1721,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/pump-app/pump-common/pump-app.matter b/examples/pump-app/pump-common/pump-app.matter index a07feba84c..92b5e7d4dc 100644 --- a/examples/pump-app/pump-common/pump-app.matter +++ b/examples/pump-app/pump-common/pump-app.matter @@ -957,7 +957,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/pump-app/silabs/data_model/pump-thread-app.matter b/examples/pump-app/silabs/data_model/pump-thread-app.matter index c56d83fc2b..503eb564a6 100644 --- a/examples/pump-app/silabs/data_model/pump-thread-app.matter +++ b/examples/pump-app/silabs/data_model/pump-thread-app.matter @@ -957,7 +957,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/pump-app/silabs/data_model/pump-wifi-app.matter b/examples/pump-app/silabs/data_model/pump-wifi-app.matter index c56d83fc2b..503eb564a6 100644 --- a/examples/pump-app/silabs/data_model/pump-wifi-app.matter +++ b/examples/pump-app/silabs/data_model/pump-wifi-app.matter @@ -957,7 +957,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/pump-controller-app/pump-controller-common/pump-controller-app.matter b/examples/pump-controller-app/pump-controller-common/pump-controller-app.matter index c4d91f94c0..8434b06997 100644 --- a/examples/pump-controller-app/pump-controller-common/pump-controller-app.matter +++ b/examples/pump-controller-app/pump-controller-common/pump-controller-app.matter @@ -832,7 +832,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/refrigerator-app/refrigerator-common/refrigerator-app.matter b/examples/refrigerator-app/refrigerator-common/refrigerator-app.matter index b99237cdfd..6d09035b04 100644 --- a/examples/refrigerator-app/refrigerator-common/refrigerator-app.matter +++ b/examples/refrigerator-app/refrigerator-common/refrigerator-app.matter @@ -561,7 +561,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/refrigerator-app/silabs/data_model/refrigerator-thread-app.matter b/examples/refrigerator-app/silabs/data_model/refrigerator-thread-app.matter index 838776ac2a..c8fa6629d9 100644 --- a/examples/refrigerator-app/silabs/data_model/refrigerator-thread-app.matter +++ b/examples/refrigerator-app/silabs/data_model/refrigerator-thread-app.matter @@ -811,7 +811,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/refrigerator-app/silabs/data_model/refrigerator-wifi-app.matter b/examples/refrigerator-app/silabs/data_model/refrigerator-wifi-app.matter index 530f00d32f..3c871bb6d9 100644 --- a/examples/refrigerator-app/silabs/data_model/refrigerator-wifi-app.matter +++ b/examples/refrigerator-app/silabs/data_model/refrigerator-wifi-app.matter @@ -811,7 +811,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/rvc-app/rvc-common/rvc-app.matter b/examples/rvc-app/rvc-common/rvc-app.matter index 512f54cfd7..c826cf0b1d 100644 --- a/examples/rvc-app/rvc-common/rvc-app.matter +++ b/examples/rvc-app/rvc-common/rvc-app.matter @@ -585,7 +585,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/smoke-co-alarm-app/smoke-co-alarm-common/smoke-co-alarm-app.matter b/examples/smoke-co-alarm-app/smoke-co-alarm-common/smoke-co-alarm-app.matter index 1399ecb7c1..0bf2d1ca1c 100644 --- a/examples/smoke-co-alarm-app/smoke-co-alarm-common/smoke-co-alarm-app.matter +++ b/examples/smoke-co-alarm-app/smoke-co-alarm-common/smoke-co-alarm-app.matter @@ -1075,7 +1075,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; 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 75105aaad3..44828bad25 100644 --- a/examples/temperature-measurement-app/temperature-measurement-common/temperature-measurement.matter +++ b/examples/temperature-measurement-app/temperature-measurement-common/temperature-measurement.matter @@ -715,7 +715,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/terms-and-conditions-app/terms-and-conditions-common/terms-and-conditions-app.matter b/examples/terms-and-conditions-app/terms-and-conditions-common/terms-and-conditions-app.matter index 2193844bf1..78d60f2bc1 100644 --- a/examples/terms-and-conditions-app/terms-and-conditions-common/terms-and-conditions-app.matter +++ b/examples/terms-and-conditions-app/terms-and-conditions-common/terms-and-conditions-app.matter @@ -734,7 +734,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/thermostat/nxp/zap/thermostat_matter_br.matter b/examples/thermostat/nxp/zap/thermostat_matter_br.matter index e2847b561b..2facf0aae2 100644 --- a/examples/thermostat/nxp/zap/thermostat_matter_br.matter +++ b/examples/thermostat/nxp/zap/thermostat_matter_br.matter @@ -739,7 +739,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/thermostat/nxp/zap/thermostat_matter_thread.matter b/examples/thermostat/nxp/zap/thermostat_matter_thread.matter index db8bc803bf..730ed8ffab 100644 --- a/examples/thermostat/nxp/zap/thermostat_matter_thread.matter +++ b/examples/thermostat/nxp/zap/thermostat_matter_thread.matter @@ -739,7 +739,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/thermostat/nxp/zap/thermostat_matter_wifi.matter b/examples/thermostat/nxp/zap/thermostat_matter_wifi.matter index 12daa4885e..50e24d2fa7 100644 --- a/examples/thermostat/nxp/zap/thermostat_matter_wifi.matter +++ b/examples/thermostat/nxp/zap/thermostat_matter_wifi.matter @@ -739,7 +739,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/thermostat/qpg/zap/thermostaticRadiatorValve.matter b/examples/thermostat/qpg/zap/thermostaticRadiatorValve.matter index 96ed93bd8c..1f698fd853 100644 --- a/examples/thermostat/qpg/zap/thermostaticRadiatorValve.matter +++ b/examples/thermostat/qpg/zap/thermostaticRadiatorValve.matter @@ -913,7 +913,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/thermostat/thermostat-common/thermostat.matter b/examples/thermostat/thermostat-common/thermostat.matter index 03cb546d1f..e80ed1ee9a 100644 --- a/examples/thermostat/thermostat-common/thermostat.matter +++ b/examples/thermostat/thermostat-common/thermostat.matter @@ -974,7 +974,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/thread-br-app/thread-br-common/thread-br-app.matter b/examples/thread-br-app/thread-br-common/thread-br-app.matter index b1ef02cd5a..06e5778747 100644 --- a/examples/thread-br-app/thread-br-common/thread-br-app.matter +++ b/examples/thread-br-app/thread-br-common/thread-br-app.matter @@ -535,7 +535,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/tv-app/tv-common/tv-app.matter b/examples/tv-app/tv-common/tv-app.matter index 1023de099d..ba6b776619 100644 --- a/examples/tv-app/tv-common/tv-app.matter +++ b/examples/tv-app/tv-common/tv-app.matter @@ -937,7 +937,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -1029,7 +1029,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; 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 d02a997c5e..7654b66be3 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 @@ -1000,7 +1000,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; 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 ad1da15819..39ba8c628e 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 @@ -1177,7 +1177,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/water-leak-detector-app/water-leak-detector-common/water-leak-detector-app.matter b/examples/water-leak-detector-app/water-leak-detector-common/water-leak-detector-app.matter index cb185ad5ea..854d7eeace 100644 --- a/examples/water-leak-detector-app/water-leak-detector-common/water-leak-detector-app.matter +++ b/examples/water-leak-detector-app/water-leak-detector-common/water-leak-detector-app.matter @@ -938,7 +938,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/examples/window-app/common/window-app.matter b/examples/window-app/common/window-app.matter index 0cec2be0cf..916dfc2305 100644 --- a/examples/window-app/common/window-app.matter +++ b/examples/window-app/common/window-app.matter @@ -1101,7 +1101,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/src/app/zap-templates/zcl/data-model/chip/general-commissioning-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/general-commissioning-cluster.xml index f7f81c3f59..9c40b13972 100644 --- a/src/app/zap-templates/zcl/data-model/chip/general-commissioning-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/general-commissioning-cluster.xml @@ -105,7 +105,7 @@ limitations under the License. - + diff --git a/src/controller/data_model/controller-clusters.matter b/src/controller/data_model/controller-clusters.matter index 1ba302c385..2c9d83a604 100644 --- a/src/controller/data_model/controller-clusters.matter +++ b/src/controller/data_model/controller-clusters.matter @@ -1582,7 +1582,7 @@ cluster GeneralCommissioning = 48 { provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; - provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + provisional readonly attribute access(read: administer) optional nullable int32u TCUpdateDeadline = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; diff --git a/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java b/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java index da6e6e5c7d..11f48e86be 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java @@ -8178,6 +8178,10 @@ public interface BasicCommissioningInfoAttributeCallback extends BaseAttributeCa void onSuccess(ChipStructs.GeneralCommissioningClusterBasicCommissioningInfo value); } + public interface TCUpdateDeadlineAttributeCallback extends BaseAttributeCallback { + void onSuccess(@Nullable Long value); + } + public interface GeneratedCommandListAttributeCallback extends BaseAttributeCallback { void onSuccess(List value); } @@ -8438,26 +8442,26 @@ public void onSuccess(byte[] tlv) { } public void readTCUpdateDeadlineAttribute( - LongAttributeCallback callback) { + TCUpdateDeadlineAttributeCallback callback) { ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, TC_UPDATE_DEADLINE_ATTRIBUTE_ID); readAttribute(new ReportCallbackImpl(callback, path) { @Override public void onSuccess(byte[] tlv) { - Long value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + @Nullable Long value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); callback.onSuccess(value); } }, TC_UPDATE_DEADLINE_ATTRIBUTE_ID, true); } public void subscribeTCUpdateDeadlineAttribute( - LongAttributeCallback callback, int minInterval, int maxInterval) { + TCUpdateDeadlineAttributeCallback callback, int minInterval, int maxInterval) { ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, TC_UPDATE_DEADLINE_ATTRIBUTE_ID); subscribeAttribute(new ReportCallbackImpl(callback, path) { @Override public void onSuccess(byte[] tlv) { - Long value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + @Nullable Long value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); callback.onSuccess(value); } }, TC_UPDATE_DEADLINE_ATTRIBUTE_ID, minInterval, maxInterval); diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java index 695ff9a321..73cd2334b5 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java @@ -2735,6 +2735,27 @@ public void onError(Exception ex) { } } + public static class DelegatedGeneralCommissioningClusterTCUpdateDeadlineAttributeCallback implements ChipClusters.GeneralCommissioningCluster.TCUpdateDeadlineAttributeCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(@Nullable Long value) { + Map responseValues = new LinkedHashMap<>(); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Long"); + responseValues.put(commandResponseInfo, value); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception ex) { + callback.onFailure(ex); + } + } + public static class DelegatedGeneralCommissioningClusterGeneratedCommandListAttributeCallback implements ChipClusters.GeneralCommissioningCluster.GeneratedCommandListAttributeCallback, DelegatedClusterCallback { private ClusterCommandCallback callback; @Override diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java index 50528ea54b..79829bf02a 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java @@ -2430,10 +2430,10 @@ private static Map readGeneralCommissioningInteractionI InteractionInfo readGeneralCommissioningTCUpdateDeadlineAttributeInteractionInfo = new InteractionInfo( (cluster, callback, commandArguments) -> { ((ChipClusters.GeneralCommissioningCluster) cluster).readTCUpdateDeadlineAttribute( - (ChipClusters.LongAttributeCallback) callback + (ChipClusters.GeneralCommissioningCluster.TCUpdateDeadlineAttributeCallback) callback ); }, - () -> new ClusterInfoMapping.DelegatedLongAttributeCallback(), + () -> new ClusterInfoMapping.DelegatedGeneralCommissioningClusterTCUpdateDeadlineAttributeCallback(), readGeneralCommissioningTCUpdateDeadlineCommandParams ); result.put("readTCUpdateDeadlineAttribute", readGeneralCommissioningTCUpdateDeadlineAttributeInteractionInfo); diff --git a/src/controller/java/generated/java/matter/controller/cluster/clusters/GeneralCommissioningCluster.kt b/src/controller/java/generated/java/matter/controller/cluster/clusters/GeneralCommissioningCluster.kt index 93fafc69f4..f2b48cd806 100644 --- a/src/controller/java/generated/java/matter/controller/cluster/clusters/GeneralCommissioningCluster.kt +++ b/src/controller/java/generated/java/matter/controller/cluster/clusters/GeneralCommissioningCluster.kt @@ -70,6 +70,16 @@ class GeneralCommissioningCluster( object SubscriptionEstablished : BasicCommissioningInfoAttributeSubscriptionState() } + class TCUpdateDeadlineAttribute(val value: UInt?) + + sealed class TCUpdateDeadlineAttributeSubscriptionState { + data class Success(val value: UInt?) : TCUpdateDeadlineAttributeSubscriptionState() + + data class Error(val exception: Exception) : TCUpdateDeadlineAttributeSubscriptionState() + + object SubscriptionEstablished : TCUpdateDeadlineAttributeSubscriptionState() + } + class GeneratedCommandListAttribute(val value: List) sealed class GeneratedCommandListAttributeSubscriptionState { @@ -1170,7 +1180,7 @@ class GeneralCommissioningCluster( } } - suspend fun readTCUpdateDeadlineAttribute(): UInt? { + suspend fun readTCUpdateDeadlineAttribute(): TCUpdateDeadlineAttribute { val ATTRIBUTE_ID: UInt = 9u val attributePath = @@ -1197,19 +1207,24 @@ class GeneralCommissioningCluster( // Decode the TLV data into the appropriate type val tlvReader = TlvReader(attributeData.data) val decodedValue: UInt? = - if (tlvReader.isNextTag(AnonymousTag)) { - tlvReader.getUInt(AnonymousTag) + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } } else { + tlvReader.getNull(AnonymousTag) null } - return decodedValue + return TCUpdateDeadlineAttribute(decodedValue) } suspend fun subscribeTCUpdateDeadlineAttribute( minInterval: Int, maxInterval: Int, - ): Flow { + ): Flow { val ATTRIBUTE_ID: UInt = 9u val attributePaths = listOf( @@ -1228,7 +1243,7 @@ class GeneralCommissioningCluster( when (subscriptionState) { is SubscriptionState.SubscriptionErrorNotification -> { emit( - UIntSubscriptionState.Error( + TCUpdateDeadlineAttributeSubscriptionState.Error( Exception( "Subscription terminated with error code: ${subscriptionState.terminationCause}" ) @@ -1248,16 +1263,21 @@ class GeneralCommissioningCluster( // Decode the TLV data into the appropriate type val tlvReader = TlvReader(attributeData.data) val decodedValue: UInt? = - if (tlvReader.isNextTag(AnonymousTag)) { - tlvReader.getUInt(AnonymousTag) + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } } else { + tlvReader.getNull(AnonymousTag) null } - decodedValue?.let { emit(UIntSubscriptionState.Success(it)) } + decodedValue?.let { emit(TCUpdateDeadlineAttributeSubscriptionState.Success(it)) } } SubscriptionState.SubscriptionEstablished -> { - emit(UIntSubscriptionState.SubscriptionEstablished) + emit(TCUpdateDeadlineAttributeSubscriptionState.SubscriptionEstablished) } } } diff --git a/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp b/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp index a2b2c44cb9..2779d18140 100644 --- a/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp +++ b/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp @@ -4900,11 +4900,18 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR return nullptr; } jobject value; - std::string valueClassName = "java/lang/Long"; - std::string valueCtorSignature = "(J)V"; - jlong jnivalue = static_cast(cppValue); - chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), - jnivalue, value); + if (cppValue.IsNull()) + { + value = nullptr; + } + else + { + std::string valueClassName = "java/lang/Long"; + std::string valueCtorSignature = "(J)V"; + jlong jnivalue = static_cast(cppValue.Value()); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), + jnivalue, value); + } return value; } case Attributes::GeneratedCommandList::Id: { diff --git a/src/controller/python/chip/clusters/Objects.py b/src/controller/python/chip/clusters/Objects.py index 0a8f62def3..2b0282bb9d 100644 --- a/src/controller/python/chip/clusters/Objects.py +++ b/src/controller/python/chip/clusters/Objects.py @@ -6243,7 +6243,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="TCMinRequiredVersion", Tag=0x00000006, Type=typing.Optional[uint]), ClusterObjectFieldDescriptor(Label="TCAcknowledgements", Tag=0x00000007, Type=typing.Optional[uint]), ClusterObjectFieldDescriptor(Label="TCAcknowledgementsRequired", Tag=0x00000008, Type=typing.Optional[bool]), - ClusterObjectFieldDescriptor(Label="TCUpdateDeadline", Tag=0x00000009, Type=typing.Optional[uint]), + ClusterObjectFieldDescriptor(Label="TCUpdateDeadline", Tag=0x00000009, Type=typing.Union[None, Nullable, uint]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), @@ -6260,7 +6260,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: TCMinRequiredVersion: typing.Optional[uint] = None TCAcknowledgements: typing.Optional[uint] = None TCAcknowledgementsRequired: typing.Optional[bool] = None - TCUpdateDeadline: typing.Optional[uint] = None + TCUpdateDeadline: typing.Union[None, Nullable, uint] = None generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) @@ -6608,9 +6608,9 @@ def attribute_id(cls) -> int: @ChipUtility.classproperty def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) + return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: typing.Optional[uint] = None + value: typing.Union[None, Nullable, uint] = None @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm index 6fef7f4889..d4d01127b2 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm @@ -2263,8 +2263,12 @@ static id _Nullable DecodeAttributeValueForGeneralCommissioningCluster(Attribute if (*aError != CHIP_NO_ERROR) { return nil; } - NSNumber * _Nonnull value; - value = [NSNumber numberWithUnsignedInt:cppValue]; + NSNumber * _Nullable value; + if (cppValue.IsNull()) { + value = nil; + } else { + value = [NSNumber numberWithUnsignedInt:cppValue.Value()]; + } return value; } default: { diff --git a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp index 479c68f4ea..f8d7ab3cbb 100644 --- a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp +++ b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp @@ -5391,7 +5391,7 @@ Protocols::InteractionModel::Status Set(EndpointId endpoint, bool value) namespace TCUpdateDeadline { -Protocols::InteractionModel::Status Get(EndpointId endpoint, uint32_t * value) +Protocols::InteractionModel::Status Get(EndpointId endpoint, DataModel::Nullable & value) { using Traits = NumericAttributeTraits; Traits::StorageType temp; @@ -5399,18 +5399,21 @@ Protocols::InteractionModel::Status Get(EndpointId endpoint, uint32_t * value) Protocols::InteractionModel::Status status = emberAfReadAttribute(endpoint, Clusters::GeneralCommissioning::Id, Id, readable, sizeof(temp)); VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); - if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) + if (Traits::IsNullValue(temp)) { - return Protocols::InteractionModel::Status::ConstraintError; + value.SetNull(); + } + else + { + value.SetNonNull() = Traits::StorageToWorking(temp); } - *value = Traits::StorageToWorking(temp); return status; } Protocols::InteractionModel::Status Set(EndpointId endpoint, uint32_t value, MarkAttributeDirty markDirty) { using Traits = NumericAttributeTraits; - if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) { return Protocols::InteractionModel::Status::ConstraintError; } @@ -5424,7 +5427,7 @@ Protocols::InteractionModel::Status Set(EndpointId endpoint, uint32_t value, Mar Protocols::InteractionModel::Status Set(EndpointId endpoint, uint32_t value) { using Traits = NumericAttributeTraits; - if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) { return Protocols::InteractionModel::Status::ConstraintError; } @@ -5434,6 +5437,46 @@ Protocols::InteractionModel::Status Set(EndpointId endpoint, uint32_t value) return emberAfWriteAttribute(endpoint, Clusters::GeneralCommissioning::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE); } +Protocols::InteractionModel::Status SetNull(EndpointId endpoint, MarkAttributeDirty markDirty) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType value; + Traits::SetNull(value); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); + return emberAfWriteAttribute(ConcreteAttributePath(endpoint, Clusters::GeneralCommissioning::Id, Id), + EmberAfWriteDataInput(writable, ZCL_INT32U_ATTRIBUTE_TYPE).SetMarkDirty(markDirty)); +} + +Protocols::InteractionModel::Status SetNull(EndpointId endpoint) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType value; + Traits::SetNull(value); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); + return emberAfWriteAttribute(endpoint, Clusters::GeneralCommissioning::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE); +} + +Protocols::InteractionModel::Status Set(EndpointId endpoint, const chip::app::DataModel::Nullable & value, + MarkAttributeDirty markDirty) +{ + if (value.IsNull()) + { + return SetNull(endpoint, markDirty); + } + + return Set(endpoint, value.Value(), markDirty); +} + +Protocols::InteractionModel::Status Set(EndpointId endpoint, const chip::app::DataModel::Nullable & value) +{ + if (value.IsNull()) + { + return SetNull(endpoint); + } + + return Set(endpoint, value.Value()); +} + } // namespace TCUpdateDeadline namespace FeatureMap { diff --git a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h index e213f56658..cd7ad25b3d 100644 --- a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h +++ b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h @@ -835,9 +835,14 @@ Protocols::InteractionModel::Status Set(EndpointId endpoint, bool value, MarkAtt } // namespace TCAcknowledgementsRequired namespace TCUpdateDeadline { -Protocols::InteractionModel::Status Get(EndpointId endpoint, uint32_t * value); // int32u +Protocols::InteractionModel::Status Get(EndpointId endpoint, DataModel::Nullable & value); // int32u Protocols::InteractionModel::Status Set(EndpointId endpoint, uint32_t value); Protocols::InteractionModel::Status Set(EndpointId endpoint, uint32_t value, MarkAttributeDirty markDirty); +Protocols::InteractionModel::Status SetNull(EndpointId endpoint); +Protocols::InteractionModel::Status SetNull(EndpointId endpoint, MarkAttributeDirty markDirty); +Protocols::InteractionModel::Status Set(EndpointId endpoint, const chip::app::DataModel::Nullable & value); +Protocols::InteractionModel::Status Set(EndpointId endpoint, const chip::app::DataModel::Nullable & value, + MarkAttributeDirty markDirty); } // namespace TCUpdateDeadline namespace FeatureMap { 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 5d40eb84f4..266b897a04 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 @@ -6432,9 +6432,9 @@ struct TypeInfo namespace TCUpdateDeadline { struct TypeInfo { - using Type = uint32_t; - using DecodableType = uint32_t; - using DecodableArgType = uint32_t; + using Type = chip::app::DataModel::Nullable; + using DecodableType = chip::app::DataModel::Nullable; + using DecodableArgType = const chip::app::DataModel::Nullable &; static constexpr ClusterId GetClusterId() { return Clusters::GeneralCommissioning::Id; } static constexpr AttributeId GetAttributeId() { return Attributes::TCUpdateDeadline::Id; } @@ -6491,7 +6491,7 @@ struct TypeInfo Attributes::TCMinRequiredVersion::TypeInfo::DecodableType TCMinRequiredVersion = static_cast(0); Attributes::TCAcknowledgements::TypeInfo::DecodableType TCAcknowledgements = static_cast(0); Attributes::TCAcknowledgementsRequired::TypeInfo::DecodableType TCAcknowledgementsRequired = static_cast(0); - Attributes::TCUpdateDeadline::TypeInfo::DecodableType TCUpdateDeadline = static_cast(0); + Attributes::TCUpdateDeadline::TypeInfo::DecodableType TCUpdateDeadline; Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; diff --git a/zzz_generated/chip-tool/zap-generated/cluster/Commands.h b/zzz_generated/chip-tool/zap-generated/cluster/Commands.h index 64443e9d43..594e2a7ed8 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/Commands.h +++ b/zzz_generated/chip-tool/zap-generated/cluster/Commands.h @@ -18511,8 +18511,9 @@ void registerClusterGeneralCommissioning(Commands & commands, CredentialIssuerCo WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "tcacknowledgements-required", 0, 1, Attributes::TCAcknowledgementsRequired::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>(Id, "tcupdate-deadline", 0, UINT32_MAX, Attributes::TCUpdateDeadline::Id, - WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>>(Id, "tcupdate-deadline", 0, UINT32_MAX, + Attributes::TCUpdateDeadline::Id, + WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "generated-command-list", Attributes::GeneratedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // 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 d8e5a71be0..f8329e7074 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp +++ b/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp @@ -11754,7 +11754,7 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP return DataModelLogger::LogValue("TCAcknowledgementsRequired", 1, value); } case GeneralCommissioning::Attributes::TCUpdateDeadline::Id: { - uint32_t value; + chip::app::DataModel::Nullable value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogValue("TCUpdateDeadline", 1, value); } From 7a2733edc17d735fc8ffe3010a7ed71f5f9fd264 Mon Sep 17 00:00:00 2001 From: Pradip De Date: Fri, 7 Feb 2025 22:47:47 +0000 Subject: [PATCH 36/39] Add TCP bitflag checks to TC_SC_4_3 test. (#37347) --- src/python_testing/TC_SC_4_3.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/python_testing/TC_SC_4_3.py b/src/python_testing/TC_SC_4_3.py index e0ce02d2a5..42082e875f 100644 --- a/src/python_testing/TC_SC_4_3.py +++ b/src/python_testing/TC_SC_4_3.py @@ -152,6 +152,19 @@ def verify_t_value(self, t_value): return True, f"T value ({t_value}) is valid and bit 0 is clear." else: return False, f"Bit 0 is not clear. T value ({t_value})" + + # Check that the value can be either 2, 4 or 6 depending on whether + # DUT is a TCPClient, TCPServer or both. + if self.check_pics("MCORE.SC.TCP"): + if (T_int & 0x04 != 0): + return True, f"T value ({t_value}) represents valid TCP support info." + else: + return False, f"T value ({t_value}) does not have TCP bits set even though the MCORE.SC.TCP PICS indicates it is required." + else: + if (T_int & 0x04 != 0): + return False, f"T value ({t_value}) has the TCP bits set even though the MCORE.SC.TCP PICS is not set." + else: + return True, f"T value ({t_value}) is valid." except ValueError: return False, f"T value ({t_value}) is not a valid integer" From 9a18149a6809e5861f8184122a6cca057b950582 Mon Sep 17 00:00:00 2001 From: Yufeng Wang Date: Fri, 7 Feb 2025 16:25:41 -0800 Subject: [PATCH 37/39] Enable integration test during coverage statistic (#37467) * Emable python tests during coverage * Enable integration test during coverage statistic * Update build_linux_gcc_coverage --- .github/workflows/build.yaml | 22 ++++++++-------------- scripts/build_coverage.sh | 11 ++++++++++- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index bcccb51a49..24ef4842fb 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -81,14 +81,6 @@ jobs: run: scripts/run_in_build_env.sh "ninja -C ./out" - name: Run Tests run: scripts/tests/gn_tests.sh - # TODO Log Upload https://github.com/project-chip/connectedhomeip/issues/2227 - # TODO https://github.com/project-chip/connectedhomeip/issues/1512 - # - name: Run Code Coverage - # if: ${{ contains('main', env.BUILD_TYPE) }} - # run: scripts/tools/codecoverage.sh - # - name: Upload Code Coverage - # if: ${{ contains('main', env.BUILD_TYPE) }} - # run: bash <(curl -s https://codecov.io/bash) - name: Set up Build Without Detail Logging run: scripts/build/gn_gen.sh --args="chip_detail_logging=false" - name: Run Build Without Detail Logging @@ -488,16 +480,16 @@ jobs: build_linux_gcc_coverage: name: Build on Linux (coverage) - runs-on: ubuntu-latest + env: + TSAN_OPTIONS: "halt_on_error=1 suppressions=scripts/tests/chiptest/tsan-linux-suppressions.txt" + if: github.actor != 'restyled-io[bot]' + runs-on: ubuntu-latest container: image: ghcr.io/project-chip/chip-build:104 - volumes: - - "/:/runner-root-volume" - - "/tmp/log_output:/tmp/test_logs" options: --privileged --sysctl "net.ipv6.conf.all.disable_ipv6=0 - net.ipv4.conf.all.forwarding=1 net.ipv6.conf.all.forwarding=1" + net.ipv4.conf.all.forwarding=0 net.ipv6.conf.all.forwarding=0" steps: - name: Checkout @@ -506,6 +498,8 @@ jobs: uses: ./.github/actions/checkout-submodules-and-bootstrap with: platform: linux + bootstrap-log-name: bootstrap-logs-linux-${{ matrix.build_variant }}${{ matrix.chip_tool }} - name: Run Build Coverage - run: ./scripts/build_coverage.sh + run: ./scripts/build_coverage.sh --yaml + diff --git a/scripts/build_coverage.sh b/scripts/build_coverage.sh index c9d942e845..2cf3f13ee1 100755 --- a/scripts/build_coverage.sh +++ b/scripts/build_coverage.sh @@ -161,11 +161,20 @@ if [ "$skip_gn" == false ]; then scripts/run_in_build_env.sh \ "./scripts/tests/run_test_suite.py \ + --runner chip_tool_python \ + --exclude-tags MANUAL \ + --exclude-tags FLAKY \ + --exclude-tags IN_DEVELOPMENT \ + --exclude-tags EXTRA_SLOW \ + --exclude-tags SLOW \ + --exclude-tags PURPOSEFUL_FAILURE \ --chip-tool \"$OUTPUT_ROOT/chip-tool\" \ + --target TestUserLabelCluster \ run \ --iterations 1 \ --test-timeout-seconds 120 \ - --all-clusters-app \"$OUTPUT_ROOT/chip-all-clusters-app\"" + --all-clusters-app \"$OUTPUT_ROOT/chip-all-clusters-app\" \ + " fi # From ed1babf1fbf22ed1e1894fb50ce7cc4ebb9861ce Mon Sep 17 00:00:00 2001 From: Andy Salisbury Date: Fri, 7 Feb 2025 19:31:37 -0500 Subject: [PATCH 38/39] Convert reference to gen_config.h to the correct header file. (#37464) --- .../administrator-commissioning-server.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/clusters/administrator-commissioning-server/administrator-commissioning-server.cpp b/src/app/clusters/administrator-commissioning-server/administrator-commissioning-server.cpp index b39a6d44ad..65b747dd93 100644 --- a/src/app/clusters/administrator-commissioning-server/administrator-commissioning-server.cpp +++ b/src/app/clusters/administrator-commissioning-server/administrator-commissioning-server.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -38,7 +39,6 @@ #include #include #include -#include using namespace chip; using namespace chip::app; From cd58e5e6d79cd2a4046c0e60a7c2943e1f66c778 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Sat, 8 Feb 2025 12:55:47 -0500 Subject: [PATCH 39/39] Improve logging around sending XPC messages. (#37480) Log self and the method involved, so we know what's failing on what objects. --- src/darwin/Framework/CHIP/MTRDefines_Internal.h | 15 +++++++++------ src/darwin/Framework/CHIP/MTRDevice_XPC.mm | 8 ++++---- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/darwin/Framework/CHIP/MTRDefines_Internal.h b/src/darwin/Framework/CHIP/MTRDefines_Internal.h index a93be2e6cf..a0635fd1fc 100644 --- a/src/darwin/Framework/CHIP/MTRDefines_Internal.h +++ b/src/darwin/Framework/CHIP/MTRDefines_Internal.h @@ -86,13 +86,14 @@ typedef struct {} variable_hidden_by_mtr_hide; \ @try { \ [[xpcConnection synchronousRemoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { \ - MTR_LOG_ERROR("Error: %@", error); \ + MTR_LOG_ERROR("%@ Error in %@ getter: %@", self, NSStringFromSelector(_cmd), error); \ }] PREFIX \ GETTER_NAME:^(TYPE returnValue) { \ outValue = returnValue; \ }]; \ } @catch (NSException * exception) { \ - MTR_LOG_ERROR("Exception sending XPC messsage: %@", exception); \ + MTR_LOG_ERROR("%@ Exception sending XPC messsage for %@ getter: %@", self, \ + NSStringFromSelector(_cmd), exception); \ outValue = DEFAULT_VALUE; \ } \ return outValue; \ @@ -106,10 +107,11 @@ typedef struct {} variable_hidden_by_mtr_hide; \ @try { \ [[xpcConnection remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { \ - MTR_LOG_ERROR("Error: %@", error); \ + MTR_LOG_ERROR("%@ Error in %@: %@", self, NSStringFromSelector(_cmd), error); \ }] PREFIX ADDITIONAL_ARGUMENTS]; \ } @catch (NSException * exception) { \ - MTR_LOG_ERROR("Exception sending XPC messsage: %@", exception); \ + MTR_LOG_ERROR("%@ Exception sending XPC messsage for %@: %@", self, \ + NSStringFromSelector(_cmd), exception); \ } \ } @@ -122,12 +124,13 @@ typedef struct {} variable_hidden_by_mtr_hide; \ @try { \ [[xpcConnection synchronousRemoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { \ - MTR_LOG_ERROR("Error: %@", error); \ + MTR_LOG_ERROR("%@ Error in %@: %@", self, NSStringFromSelector(_cmd), error); \ }] PREFIX ADDITIONAL_ARGUMENTS:^(TYPE returnValue) { \ outValue = returnValue; \ }]; \ } @catch (NSException * exception) { \ - MTR_LOG_ERROR("Exception sending XPC messsage: %@", exception); \ + MTR_LOG_ERROR("%@ Exception sending XPC messsage for %@: %@", self, NSStringFromSelector(_cmd), \ + exception); \ outValue = DEFAULT_VALUE; \ } \ \ diff --git a/src/darwin/Framework/CHIP/MTRDevice_XPC.mm b/src/darwin/Framework/CHIP/MTRDevice_XPC.mm index fed4238f6b..056d1f1b82 100644 --- a/src/darwin/Framework/CHIP/MTRDevice_XPC.mm +++ b/src/darwin/Framework/CHIP/MTRDevice_XPC.mm @@ -467,7 +467,7 @@ - (void)invokeCommands:(NSArray *> *)c @try { [[xpcConnection remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { - MTR_LOG_ERROR("Error: %@", error); + MTR_LOG_ERROR("%@ Error in %@: %@", self, NSStringFromSelector(_cmd), error); dispatch_async(queue, ^{ completion(nil, [NSError errorWithDomain:MTRErrorDomain code:MTRErrorCodeGeneralError userInfo:nil]); }); @@ -505,7 +505,7 @@ - (void)invokeCommands:(NSArray *> *)c }); }]; } @catch (NSException * exception) { - MTR_LOG_ERROR("Exception sending XPC message: %@", exception); + MTR_LOG_ERROR("%@ Exception sending XPC message for %@: %@", self, NSStringFromSelector(_cmd), exception); dispatch_async(queue, ^{ completion(nil, [NSError errorWithDomain:MTRErrorDomain code:MTRErrorCodeGeneralError userInfo:nil]); }); @@ -521,7 +521,7 @@ - (void)downloadLogOfType:(MTRDiagnosticLogType)type @try { [[xpcConnection remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { - MTR_LOG_ERROR("Error: %@", error); + MTR_LOG_ERROR("%@ Error in %@: %@", self, NSStringFromSelector(_cmd), error); dispatch_async(queue, ^{ completion(nil, [NSError errorWithDomain:MTRErrorDomain code:MTRErrorCodeGeneralError userInfo:nil]); }); @@ -538,7 +538,7 @@ - (void)downloadLogOfType:(MTRDiagnosticLogType)type }); }]; } @catch (NSException * exception) { - MTR_LOG_ERROR("Exception sending XPC messsage: %@", exception); + MTR_LOG_ERROR("%@ Exception sending XPC messsage for %@: %@", self, NSStringFromSelector(_cmd), exception); dispatch_async(queue, ^{ completion(nil, [NSError errorWithDomain:MTRErrorDomain code:MTRErrorCodeGeneralError userInfo:nil]); });