diff --git a/src/app/AttributePathParams.h b/src/app/AttributePathParams.h index effb97da71b981..adfc77cfe27830 100644 --- a/src/app/AttributePathParams.h +++ b/src/app/AttributePathParams.h @@ -96,7 +96,7 @@ struct AttributePathParams return true; } - bool IsAttributePathOverlapped(const AttributePathParams & other) const + bool Intersects(const AttributePathParams & other) const { VerifyOrReturnError(HasWildcardEndpointId() || other.HasWildcardEndpointId() || mEndpointId == other.mEndpointId, false); VerifyOrReturnError(HasWildcardClusterId() || other.HasWildcardClusterId() || mClusterId == other.mClusterId, false); diff --git a/src/app/ClusterStateCache.cpp b/src/app/ClusterStateCache.cpp index fad5c665389771..748294df725adb 100644 --- a/src/app/ClusterStateCache.cpp +++ b/src/app/ClusterStateCache.cpp @@ -454,31 +454,32 @@ CHIP_ERROR ClusterStateCache::OnUpdateDataVersionFilterList(DataVersionFilterIBs CHIP_ERROR err = CHIP_NO_ERROR; TLV::TLVWriter backup; - for (auto & attribute : aAttributePaths) - { - if (attribute.HasWildcardAttributeId()) - { - mRequestPathSet.insert(attribute); - } - } - + // Only put paths into mRequestPathSet if they cover clusters in their entirety and no other path in our path list + // points to a specific attribute from any of those clusters. + // this would help for data-out-of-sync issue when handling store data version for the particular case on two paths: (E1, C1, + // wildcard), (wildcard, C1, A1) for (auto & attribute1 : aAttributePaths) { + bool intersected = false; if (attribute1.HasWildcardAttributeId()) { - continue; - } - - auto attribute2 = std::begin(mRequestPathSet); - while (attribute2 != std::end(mRequestPathSet)) - { - if (attribute1.IsAttributePathOverlapped(*attribute2)) + for (auto & attribute2 : aAttributePaths) { - attribute2 = mRequestPathSet.erase(attribute2); + if (attribute2.HasWildcardAttributeId()) + { + continue; + } + + if (attribute1.Intersects(attribute2)) + { + intersected = true; + break; + } } - else + + if (!intersected) { - ++attribute2; + mRequestPathSet.insert(attribute1); } } } diff --git a/src/controller/tests/data_model/TestRead.cpp b/src/controller/tests/data_model/TestRead.cpp index defda1c95f9e79..5d93aad5e7a9f0 100644 --- a/src/controller/tests/data_model/TestRead.cpp +++ b/src/controller/tests/data_model/TestRead.cpp @@ -431,7 +431,8 @@ void TestReadInteraction::TestReadSubscribeAttributeResponseWithCache(nlTestSuit NL_TEST_ASSERT(apSuite, delegate.mNumAttributeResponse == 6); NL_TEST_ASSERT(apSuite, !delegate.mReadError); Optional version1; - NL_TEST_ASSERT(apSuite, cache.GetVersion(Test::kMockEndpoint2, Test::MockClusterId(3), version1) == CHIP_NO_ERROR); + app::ConcreteClusterPath clusterPath1(Test::kMockEndpoint2, Test::MockClusterId(3)); + NL_TEST_ASSERT(apSuite, cache.GetVersion(clusterPath1, version1) == CHIP_NO_ERROR); NL_TEST_ASSERT(apSuite, !version1.HasValue()); delegate.mNumAttributeResponse = 0; }