Skip to content

Commit 4eab278

Browse files
committed
Squashed commit of a server cluster interface.
This defines a ServerClusterInterface class along with a registry. Also slight update to build_coverage to run on more (specifically my) machines without errors. Implementation notes: - Registry does NOT allow anymore to have "wildcard register" on endpoints. This is because we expect to have attribute members (no more "free/implicit" storage from ember buffers). - Interface now includes metadata for attributes (AAI does not) and maintains the cluster version. - This does not yet include changes in #37526 (so no AAI replacement for list begin/end) as that interface gets finalized. It will have it once that PR is finalized and merged. - Registry has no "cache" but uses a "move found item to front of list". This is ok for individual requests however for full iterations it would be slower (about 2x if we always iterate over all clusters ... since then average search would be N instead of N/2 for a list that never changes). We can revisit this approach at any time This is currently unused. I expect usages to add flash & RAM cost, that will be slowly offset (especially RAM) as we move clusters around: - RAM for linked list will be one list instead of 2 (AAI to CHI) so any cluster moved that uses both would save 1 pointer metadata will increase slightly, can be reduced if we get ember to stop generating metadata for included clusters - RAM can decrease by FeatureMap and ClusterRevision if we stop ember from allocating space for it (however we will offset this by flash "encode const value"). - RAM usage increases slightly during conversion for "store version data" which ember currently allocates for all clusters. - Very long term: if we replace all clusters, we can drop AAI/CHI and that would save some flash. Still expect no savings because new interface does all of AAI and CHI and a bit more. TLDR on resourcing: probably ok on RAM over time, there is a flash overhead for this, claiming this is important for testable and maintainable code in the future.
1 parent 522876c commit 4eab278

14 files changed

+1307
-7
lines changed

docs/ids_and_codes/ERROR_CODES.md

+1
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ This file was **AUTOMATICALLY** generated by
5555
| 37 | 0x25 | `CHIP_ERROR_UNKNOWN_IMPLICIT_TLV_TAG` |
5656
| 38 | 0x26 | `CHIP_ERROR_WRONG_TLV_TYPE` |
5757
| 39 | 0x27 | `CHIP_ERROR_TLV_CONTAINER_OPEN` |
58+
| 40 | 0x28 | `CHIP_ERROR_IN_USE` |
5859
| 42 | 0x2A | `CHIP_ERROR_INVALID_MESSAGE_TYPE` |
5960
| 43 | 0x2B | `CHIP_ERROR_UNEXPECTED_TLV_ELEMENT` |
6061
| 45 | 0x2D | `CHIP_ERROR_NOT_IMPLEMENTED` |

scripts/build_coverage.sh

+4-1
Original file line numberDiff line numberDiff line change
@@ -221,15 +221,18 @@ lcov --initial --capture --directory "$OUTPUT_ROOT/obj/src" \
221221
--exclude="$PWD"/zzz_generated/* \
222222
--exclude="$PWD"/third_party/* \
223223
--exclude=/usr/include/* \
224+
--ignore-errors inconsistent \
224225
--output-file "$COVERAGE_ROOT/lcov_base.info"
225226

226227
lcov --capture --directory "$OUTPUT_ROOT/obj/src" \
227228
--exclude="$PWD"/zzz_generated/* \
228229
--exclude="$PWD"/third_party/* \
229230
--exclude=/usr/include/* \
231+
--ignore-errors inconsistent \
230232
--output-file "$COVERAGE_ROOT/lcov_test.info"
231233

232-
lcov --add-tracefile "$COVERAGE_ROOT/lcov_base.info" \
234+
lcov --ignore-errors inconsistent \
235+
--add-tracefile "$COVERAGE_ROOT/lcov_base.info" \
233236
--add-tracefile "$COVERAGE_ROOT/lcov_test.info" \
234237
--output-file "$COVERAGE_ROOT/lcov_final.info"
235238

src/BUILD.gn

+4-1
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,9 @@ if (chip_build_tests) {
5151
deps = []
5252
tests = [
5353
"${chip_root}/src/access/tests",
54-
"${chip_root}/src/app/data-model/tests",
5554
"${chip_root}/src/app/cluster-building-blocks/tests",
5655
"${chip_root}/src/app/data-model-provider/tests",
56+
"${chip_root}/src/app/data-model/tests",
5757
"${chip_root}/src/app/icd/server/tests",
5858
"${chip_root}/src/crypto/tests",
5959
"${chip_root}/src/inet/tests",
@@ -108,6 +108,9 @@ if (chip_build_tests) {
108108
# https://github.com/project-chip/connectedhomeip/issues/35624
109109
"${chip_root}/src/credentials/tests",
110110
"${chip_root}/src/lib/support/tests",
111+
112+
# Disabled on EFR32 since "include <random>" fails with `::fabs` not defined
113+
"${chip_root}/src/app/server-cluster/tests",
111114
]
112115
}
113116

src/app/data-model-provider/tests/TestActionReturnStatus.cpp

+2-4
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,11 @@
1515
* See the License for the specific language governing permissions and
1616
* limitations under the License.
1717
*/
18-
19-
#include "lib/core/CHIPError.h"
20-
#include "protocols/interaction_model/StatusCode.h"
21-
#include "pw_unit_test/framework_backend.h"
2218
#include <app/data-model-provider/ActionReturnStatus.h>
2319
#include <app/data-model-provider/StringBuilderAdapters.h>
20+
#include <lib/core/CHIPError.h>
2421
#include <lib/support/CodeUtils.h>
22+
#include <protocols/interaction_model/StatusCode.h>
2523

2624
#include <pw_unit_test/framework.h>
2725

src/app/server-cluster/BUILD.gn

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# Copyright (c) 2025 Project CHIP Authors
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
import("//build_overrides/chip.gni")
15+
16+
source_set("server-cluster") {
17+
sources = [
18+
"ServerClusterInterface.cpp",
19+
"ServerClusterInterface.h",
20+
]
21+
22+
public_deps = [
23+
"${chip_root}/src/app:attribute-access",
24+
"${chip_root}/src/app:command-handler-interface",
25+
"${chip_root}/src/app:paths",
26+
"${chip_root}/src/app/common:ids",
27+
"${chip_root}/src/app/data-model-provider",
28+
"${chip_root}/src/app/data-model-provider:metadata",
29+
"${chip_root}/src/crypto",
30+
"${chip_root}/src/lib/core:error",
31+
"${chip_root}/src/lib/core:types",
32+
"${chip_root}/src/lib/support",
33+
]
34+
}
35+
36+
source_set("registry") {
37+
sources = [
38+
"ServerClusterInterfaceRegistry.cpp",
39+
"ServerClusterInterfaceRegistry.h",
40+
]
41+
42+
public_deps = [
43+
":server-cluster",
44+
"${chip_root}/src/app:paths",
45+
"${chip_root}/src/lib/core:types",
46+
"${chip_root}/src/lib/support",
47+
]
48+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
/*
2+
* Copyright (c) 2025 Project CHIP Authors
3+
* All rights reserved.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
#include "access/Privilege.h"
18+
#include <app/server-cluster/ServerClusterInterface.h>
19+
20+
#include <app-common/zap-generated/ids/Attributes.h>
21+
#include <app/data-model-provider/MetadataTypes.h>
22+
#include <crypto/RandUtils.h>
23+
#include <lib/support/BitFlags.h>
24+
#include <optional>
25+
#include <protocols/interaction_model/StatusCode.h>
26+
27+
namespace chip {
28+
namespace app {
29+
namespace {
30+
31+
using namespace chip::app::Clusters;
32+
using namespace chip::app::DataModel;
33+
34+
constexpr AttributeEntry kGlobalAttributeEntries[] = {
35+
{
36+
Globals::Attributes::ClusterRevision::Id,
37+
BitFlags<AttributeQualityFlags>(),
38+
Access::Privilege::kView,
39+
std::nullopt,
40+
},
41+
{
42+
Globals::Attributes::FeatureMap::Id,
43+
BitFlags<AttributeQualityFlags>(),
44+
Access::Privilege::kView,
45+
std::nullopt,
46+
},
47+
{
48+
Globals::Attributes::AttributeList::Id,
49+
BitFlags<AttributeQualityFlags>(AttributeQualityFlags::kListAttribute),
50+
Access::Privilege::kView,
51+
std::nullopt,
52+
},
53+
{
54+
Globals::Attributes::AcceptedCommandList::Id,
55+
BitFlags<AttributeQualityFlags>(AttributeQualityFlags::kListAttribute),
56+
Access::Privilege::kView,
57+
std::nullopt,
58+
},
59+
{
60+
Globals::Attributes::GeneratedCommandList::Id,
61+
BitFlags<AttributeQualityFlags>(AttributeQualityFlags::kListAttribute),
62+
Access::Privilege::kView,
63+
std::nullopt,
64+
},
65+
};
66+
67+
} // namespace
68+
69+
ServerClusterInterface::ServerClusterInterface()
70+
{
71+
// SPEC - 7.10.3. Cluster Data Version
72+
// A cluster data version SHALL be initialized randomly when it is first published.
73+
mDataVersion = Crypto::GetRandU32();
74+
75+
// marks that this sever cluster interface is NOT in list
76+
mNext = this;
77+
}
78+
79+
CHIP_ERROR ServerClusterInterface::Attributes(const ConcreteClusterPath & path, DataModel::ListBuilder<AttributeEntry> & builder)
80+
{
81+
82+
return builder.ReferenceExisting(Span<const AttributeEntry>(kGlobalAttributeEntries));
83+
}
84+
85+
BitFlags<ClusterQualityFlags> ServerClusterInterface::GetClusterFlags() const
86+
{
87+
return BitFlags<ClusterQualityFlags>();
88+
}
89+
90+
ActionReturnStatus ServerClusterInterface::WriteAttribute(const WriteAttributeRequest & request, AttributeValueDecoder & decoder)
91+
{
92+
return Protocols::InteractionModel::Status::UnsupportedWrite;
93+
}
94+
95+
std::optional<ActionReturnStatus> ServerClusterInterface::Invoke(const InvokeRequest & request,
96+
chip::TLV::TLVReader & input_arguments, CommandHandler * handler)
97+
{
98+
return Protocols::InteractionModel::Status::UnsupportedCommand;
99+
}
100+
101+
CHIP_ERROR ServerClusterInterface::AcceptedCommands(const ConcreteClusterPath & path,
102+
DataModel::ListBuilder<AcceptedCommandEntry> & builder)
103+
{
104+
return CHIP_NO_ERROR;
105+
}
106+
107+
CHIP_ERROR ServerClusterInterface::GeneratedCommands(const ConcreteClusterPath & path, DataModel::ListBuilder<CommandId> & builder)
108+
{
109+
return CHIP_NO_ERROR;
110+
}
111+
112+
} // namespace app
113+
} // namespace chip

0 commit comments

Comments
 (0)