Skip to content

Commit 2bd5aa3

Browse files
andy31415andreilitvinrestyled-commitsbzbarsky-apple
authored
Make DataModel::Provider return a Complete attribute metadata as its public interface (#37519)
* Start adding complete metadata, before updating tests * Restyle * Fix codegen data model provider unit tests * Fix includes * Restyled by clang-format * Update src/data-model-providers/codegen/CodegenDataModelProvider.cpp Co-authored-by: Boris Zbarsky <bzbarsky@apple.com> * Restyle * Add/update comment about global items we add * Restyle --------- Co-authored-by: Andrei Litvin <andreilitvin@google.com> Co-authored-by: Restyled.io <commits@restyled.io> Co-authored-by: Boris Zbarsky <bzbarsky@apple.com>
1 parent a3f941a commit 2bd5aa3

File tree

4 files changed

+51
-19
lines changed

4 files changed

+51
-19
lines changed

src/app/GlobalAttributes.cpp

-8
Original file line numberDiff line numberDiff line change
@@ -97,14 +97,6 @@ DataModel::ActionReturnStatus ReadGlobalAttributeFromMetadata(DataModel::Provide
9797
// and this reduces template variants for Encode, saving flash.
9898
ReturnErrorOnFailure(listEncodeHelper.Encode(static_cast<uint64_t>(entry.attributeId)));
9999
}
100-
101-
for (auto id : GlobalAttributesNotInMetadata)
102-
{
103-
// NOTE: cast to u64 because TLV encodes all numbers the same (no TLV sideffects)
104-
// and this reduces template variants for Encode, saving flash.
105-
ReturnErrorOnFailure(listEncodeHelper.Encode(static_cast<uint64_t>(id)));
106-
}
107-
108100
return CHIP_NO_ERROR;
109101
});
110102
}

src/app/data-model-provider/ProviderMetadataTree.h

+5-5
Original file line numberDiff line numberDiff line change
@@ -60,14 +60,14 @@ class ProviderMetadataTree
6060
virtual CHIP_ERROR ClientClusters(EndpointId endpointId, ListBuilder<ClusterId> & builder) = 0;
6161
virtual CHIP_ERROR ServerClusters(EndpointId endpointId, ListBuilder<ServerClusterEntry> & builder) = 0;
6262

63-
/// Attribute lists contain all attributes EXCEPT the list attributes that
64-
/// are part of metadata. The output from this method MUST NOT contain:
65-
/// - AttributeList::Id
63+
/// Attribute lists contain all attributes. This MUST include all global
64+
/// attributes (See SPEC 7.13 Global Elements / Global Attributes Table).
65+
/// In particular this MUST contain:
6666
/// - AcceptedCommandList::Id
67-
/// - GeneratedCommandList::Id
68-
/// However it MUST ALWAYS contain:
67+
/// - AttributeList::Id
6968
/// - ClusterRevision::Id
7069
/// - FeatureMap::Id
70+
/// - GeneratedCommandList::Id
7171
virtual CHIP_ERROR Attributes(const ConcreteClusterPath & path, ListBuilder<AttributeEntry> & builder) = 0;
7272
virtual CHIP_ERROR GeneratedCommands(const ConcreteClusterPath & path, ListBuilder<CommandId> & builder) = 0;
7373
virtual CHIP_ERROR AcceptedCommands(const ConcreteClusterPath & path, ListBuilder<AcceptedCommandEntry> & builder) = 0;

src/data-model-providers/codegen/CodegenDataModelProvider.cpp

+28-2
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,15 @@
1717
#include <data-model-providers/codegen/CodegenDataModelProvider.h>
1818

1919
#include <access/AccessControl.h>
20+
#include <access/Privilege.h>
2021
#include <app-common/zap-generated/attribute-type.h>
2122
#include <app/CommandHandlerInterface.h>
2223
#include <app/CommandHandlerInterfaceRegistry.h>
2324
#include <app/ConcreteAttributePath.h>
2425
#include <app/ConcreteClusterPath.h>
2526
#include <app/ConcreteCommandPath.h>
2627
#include <app/EventPathParams.h>
28+
#include <app/GlobalAttributes.h>
2729
#include <app/RequiredPrivilege.h>
2830
#include <app/data-model-provider/MetadataList.h>
2931
#include <app/data-model-provider/MetadataTypes.h>
@@ -267,8 +269,14 @@ CHIP_ERROR CodegenDataModelProvider::Attributes(const ConcreteClusterPath & path
267269
VerifyOrReturnValue(cluster->attributeCount > 0, CHIP_NO_ERROR);
268270
VerifyOrReturnValue(cluster->attributes != nullptr, CHIP_NO_ERROR);
269271

270-
// TODO: if ember would encode data in AttributeEntry form, we could reference things directly
271-
ReturnErrorOnFailure(builder.EnsureAppendCapacity(cluster->attributeCount));
272+
// TODO: if ember would encode data in AttributeEntry form, we could reference things directly (shorter code,
273+
// although still allocation overhead due to global attributes not in metadata)
274+
//
275+
// We have Attributes from ember + global attributes that are NOT in ember metadata.
276+
// We have to report them all
277+
constexpr size_t kGlobalAttributeNotInMetadataCount = ArraySize(GlobalAttributesNotInMetadata);
278+
279+
ReturnErrorOnFailure(builder.EnsureAppendCapacity(cluster->attributeCount + kGlobalAttributeNotInMetadataCount));
272280

273281
Span<const EmberAfAttributeMetadata> attributeSpan(cluster->attributes, cluster->attributeCount);
274282

@@ -277,6 +285,24 @@ CHIP_ERROR CodegenDataModelProvider::Attributes(const ConcreteClusterPath & path
277285
ReturnErrorOnFailure(builder.Append(AttributeEntryFrom(path, attribute)));
278286
}
279287

288+
// This "GlobalListEntry" is specific for metadata that ember does not include
289+
// in its attribute list metadata.
290+
//
291+
// By spec these Attribute/AcceptedCommands/GeneratedCommants lists are:
292+
// - lists of elements
293+
// - read-only, with read privilege view
294+
// - fixed value (no such flag exists, so this is not a quality flag we set/track)
295+
DataModel::AttributeEntry globalListEntry;
296+
297+
globalListEntry.readPrivilege = Access::Privilege::kView;
298+
globalListEntry.flags.Set(DataModel::AttributeQualityFlags::kListAttribute);
299+
300+
for (auto & attribute : GlobalAttributesNotInMetadata)
301+
{
302+
globalListEntry.attributeId = attribute;
303+
ReturnErrorOnFailure(builder.Append(globalListEntry));
304+
}
305+
280306
return CHIP_NO_ERROR;
281307
}
282308

src/data-model-providers/codegen/tests/TestCodegenModelViaMocks.cpp

+18-4
Original file line numberDiff line numberDiff line change
@@ -1073,7 +1073,7 @@ TEST_F(TestCodegenModelViaMocks, IterateOverAttributes)
10731073

10741074
EXPECT_EQ(model.Attributes(ConcreteClusterPath(kMockEndpoint2, MockClusterId(2)), builder), CHIP_NO_ERROR);
10751075
auto attributes = builder.TakeBuffer();
1076-
ASSERT_EQ(attributes.size(), 4u);
1076+
ASSERT_EQ(attributes.size(), 7u);
10771077

10781078
ASSERT_EQ(attributes[0].attributeId, ClusterRevision::Id);
10791079
ASSERT_FALSE(attributes[0].flags.Has(AttributeQualityFlags::kListAttribute));
@@ -1086,6 +1086,16 @@ TEST_F(TestCodegenModelViaMocks, IterateOverAttributes)
10861086

10871087
ASSERT_EQ(attributes[3].attributeId, MockAttributeId(2));
10881088
ASSERT_TRUE(attributes[3].flags.Has(AttributeQualityFlags::kListAttribute));
1089+
1090+
// Ends with global list attributes
1091+
ASSERT_EQ(attributes[4].attributeId, GeneratedCommandList::Id);
1092+
ASSERT_TRUE(attributes[4].flags.Has(AttributeQualityFlags::kListAttribute));
1093+
1094+
ASSERT_EQ(attributes[5].attributeId, AcceptedCommandList::Id);
1095+
ASSERT_TRUE(attributes[5].flags.Has(AttributeQualityFlags::kListAttribute));
1096+
1097+
ASSERT_EQ(attributes[6].attributeId, AttributeList::Id);
1098+
ASSERT_TRUE(attributes[6].flags.Has(AttributeQualityFlags::kListAttribute));
10891099
}
10901100

10911101
TEST_F(TestCodegenModelViaMocks, FindAttribute)
@@ -1127,7 +1137,7 @@ TEST_F(TestCodegenModelViaMocks, FindAttribute)
11271137
EXPECT_FALSE(info->writePrivilege.has_value()); // NOLINT(bugprone-unchecked-optional-access)
11281138
}
11291139

1130-
// global attributes are EXPLICITLY not supported
1140+
// global attributes are EXPLICITLY supported
11311141
TEST_F(TestCodegenModelViaMocks, GlobalAttributeInfo)
11321142
{
11331143
UseMockNodeConfig config(gTestNodeConfig);
@@ -1138,10 +1148,14 @@ TEST_F(TestCodegenModelViaMocks, GlobalAttributeInfo)
11381148
std::optional<AttributeEntry> info = finder.Find(
11391149
ConcreteAttributePath(kMockEndpoint1, MockClusterId(1), Clusters::Globals::Attributes::GeneratedCommandList::Id));
11401150

1141-
ASSERT_FALSE(info.has_value());
1151+
ASSERT_TRUE(info.has_value());
11421152

11431153
info = finder.Find(ConcreteAttributePath(kMockEndpoint1, MockClusterId(1), Clusters::Globals::Attributes::AttributeList::Id));
1144-
ASSERT_FALSE(info.has_value());
1154+
ASSERT_TRUE(info.has_value());
1155+
1156+
info = finder.Find(
1157+
ConcreteAttributePath(kMockEndpoint1, MockClusterId(1), Clusters::Globals::Attributes::AcceptedCommandList::Id));
1158+
ASSERT_TRUE(info.has_value());
11451159
}
11461160

11471161
TEST_F(TestCodegenModelViaMocks, IterateOverAcceptedCommands)

0 commit comments

Comments
 (0)