Skip to content

Commit 1062968

Browse files
mlepage-googlepull[bot]
authored andcommitted
Implement ACL attribute read/write (#12305)
* Add access control server skeleton Add empty cluster implementation to all-clusters-app example. * Regen code. * Restyle code * Update from upstream changes * Restyle * Add access-control-server to CMakeLists.txt For esp32 and mbed, for all-clusters-app. * Remove nullable from list attribute Code gen isn't working yet for this possibility. * Regen and restyle * Regen and restyle * Fix test Descriptor cluster test expects certain clusters in certain order. (This is fragile and we should find a way to improve it, but just fix up the expected order for now.) * Regen and restyle * Regen and restyle * Regen and restyle * Regen and restyle * Regen and restyle * Regen and restyle * Add AccessControl cluster to Darwin test helper Until the tests use Descriptor cluster, they have a hardcoded list of clusters expected on endpoints, which must be kept accurate. * Remove AccessControl cluster from some tests Some Darwin tests are not relevant for this cluster (as for others). * Fix unless in test file Those special tags need to be closed. * Restyle and regen * Implement ACL attribute Just basic read/write of the entire list. - Not a specific index. - Not fabric-filtered. - Not with rollback if errors occur. Minor small changes to the AccessControl interface to support this work. Progress toward issue #10254 * Regen and restyle * Regen and restyle * Change extension attribute storage to RAM Until it's implemented in external storage, change its storage to RAM, so there's less issues with unimplemented cluster attributes. * Re-enable access control cluster tests Tests for ACL and extension attribute were disabled while these attributes were unimplemented. Now, ACL is implemented and extension has its storage moved to RAM (for now) so both should work. * Fix extension attribute Apparently the regen emits corrupt code if it doesn't have a length. * Restyle and regen * Change lambda arg to auto in access control server It was TagBoundEncoder, but now it's ListEncodeHelper. Also had to fix the perfect forwarding in AttributeValueEncoder and ListEncodeHelper and other template functions in the file, so it doesn't try to copy its args. * Add missing variable definitions These static constexpr member variables were declared but not defined. In C++14 and lower, the definitions are required. Otherwise, undefined reference ensues. C++17 handles this but Matter is still using C++14. Not sure why this was working before... * Regen and restyle
1 parent 000e18d commit 1062968

File tree

13 files changed

+918
-454
lines changed

13 files changed

+918
-454
lines changed

examples/all-clusters-app/all-clusters-common/all-clusters-app.zap

+3-3
Original file line numberDiff line numberDiff line change
@@ -969,7 +969,7 @@
969969
"bounded": 0,
970970
"defaultValue": "",
971971
"reportable": 1,
972-
"minInterval": 1,
972+
"minInterval": 0,
973973
"maxInterval": 65534,
974974
"reportableChange": 0
975975
},
@@ -979,12 +979,12 @@
979979
"mfgCode": null,
980980
"side": "server",
981981
"included": 1,
982-
"storageOption": "External",
982+
"storageOption": "RAM",
983983
"singleton": 0,
984984
"bounded": 0,
985985
"defaultValue": "",
986986
"reportable": 1,
987-
"minInterval": 1,
987+
"minInterval": 0,
988988
"maxInterval": 65534,
989989
"reportableChange": 0
990990
},

examples/all-clusters-app/all-clusters-common/src/bridged-actions-stub.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ class BridgedActionsAttrAccess : public AttributeAccessInterface
4848
CHIP_ERROR ReadClusterRevision(EndpointId endpoint, AttributeValueEncoder & aEncoder);
4949
};
5050

51+
constexpr uint16_t BridgedActionsAttrAccess::ClusterRevision;
52+
5153
CHIP_ERROR BridgedActionsAttrAccess::ReadActionListAttribute(EndpointId endpoint, AttributeValueEncoder & aEncoder)
5254
{
5355
// Just return an empty list

src/access/AccessControl.h

+22-3
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ class AccessControl
4444
static constexpr Flags kCluster = 1 << 0;
4545
static constexpr Flags kEndpoint = 1 << 1;
4646
static constexpr Flags kDeviceType = 1 << 2;
47-
Flags flags;
47+
Flags flags = 0;
4848
ClusterId cluster;
4949
EndpointId endpoint;
5050
DeviceTypeId deviceType;
@@ -89,6 +89,19 @@ class AccessControl
8989

9090
Entry() = default;
9191

92+
Entry(Entry && other) : mDelegate(other.mDelegate) { other.mDelegate = &mDefaultDelegate; }
93+
94+
Entry & operator=(Entry && other)
95+
{
96+
if (this != &other)
97+
{
98+
mDelegate->Release();
99+
mDelegate = other.mDelegate;
100+
other.mDelegate = &mDefaultDelegate;
101+
}
102+
return *this;
103+
}
104+
92105
Entry(const Entry &) = delete;
93106
Entry & operator=(const Entry &) = delete;
94107

@@ -292,9 +305,12 @@ class AccessControl
292305
virtual CHIP_ERROR Finish() { return CHIP_ERROR_NOT_IMPLEMENTED; }
293306

294307
// Capabilities
295-
virtual CHIP_ERROR GetMaxEntries(int & value) const { return CHIP_ERROR_NOT_IMPLEMENTED; }
308+
virtual CHIP_ERROR GetMaxEntryCount(size_t & value) const { return CHIP_ERROR_NOT_IMPLEMENTED; }
296309
// TODO: more capabilities
297310

311+
// Actualities
312+
virtual CHIP_ERROR GetEntryCount(size_t & value) const { return CHIP_ERROR_NOT_IMPLEMENTED; }
313+
298314
// Preparation
299315
virtual CHIP_ERROR PrepareEntry(Entry & entry) { return CHIP_ERROR_NOT_IMPLEMENTED; }
300316

@@ -352,7 +368,10 @@ class AccessControl
352368
CHIP_ERROR Finish();
353369

354370
// Capabilities
355-
CHIP_ERROR GetMaxEntries(int & value) const { return mDelegate.GetMaxEntries(value); }
371+
CHIP_ERROR GetMaxEntryCount(size_t & value) const { return mDelegate.GetMaxEntryCount(value); }
372+
373+
// Actualities
374+
CHIP_ERROR GetEntryCount(size_t & value) const { return mDelegate.GetEntryCount(value); }
356375

357376
/**
358377
* Prepares an entry.

src/access/examples/ExampleAccessControlDelegate.cpp

+15-1
Original file line numberDiff line numberDiff line change
@@ -968,12 +968,26 @@ class AccessControlDelegate : public AccessControl::Delegate
968968
return SaveToFlash();
969969
}
970970

971-
CHIP_ERROR GetMaxEntries(int & value) const override
971+
CHIP_ERROR GetMaxEntryCount(size_t & value) const override
972972
{
973973
value = ArraySize(EntryStorage::acl);
974974
return CHIP_NO_ERROR;
975975
}
976976

977+
CHIP_ERROR GetEntryCount(size_t & value) const override
978+
{
979+
value = 0;
980+
for (const auto & storage : EntryStorage::acl)
981+
{
982+
if (!storage.InUse())
983+
{
984+
break;
985+
}
986+
value++;
987+
}
988+
return CHIP_NO_ERROR;
989+
}
990+
977991
CHIP_ERROR PrepareEntry(Entry & entry) override
978992
{
979993
if (auto * delegate = EntryDelegate::Find(entry.GetDelegate()))

src/access/tests/TestAccessControl.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ struct EntryData
110110
NodeId subjects[kMaxSubjects] = { 0 };
111111
Target targets[kMaxTargets] = { { 0 } };
112112

113-
void Clear() { memset(this, 0, sizeof(*this)); }
113+
void Clear() { *this = EntryData(); }
114114

115115
bool IsEmpty() const { return authMode == AuthMode::kNone; }
116116

src/app/AttributeAccessInterface.h

+5-5
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ class AttributeReportBuilder
7474
* EncodeValue encodes the value field of the report, it should be called exactly once.
7575
*/
7676
template <typename... Ts>
77-
CHIP_ERROR EncodeValue(AttributeReportIBs::Builder & aAttributeReportIBs, Ts... aArgs)
77+
CHIP_ERROR EncodeValue(AttributeReportIBs::Builder & aAttributeReportIBs, Ts &&... aArgs)
7878
{
7979
return DataModel::Encode(*(aAttributeReportIBs.GetAttributeReport().GetAttributeData().GetWriter()),
8080
TLV::ContextTag(to_underlying(AttributeDataIB::Tag::kData)), std::forward<Ts>(aArgs)...);
@@ -98,7 +98,7 @@ class AttributeValueEncoder
9898
ListEncodeHelper(AttributeValueEncoder & encoder) : mAttributeValueEncoder(encoder) {}
9999

100100
template <typename... Ts>
101-
CHIP_ERROR Encode(Ts... aArgs) const
101+
CHIP_ERROR Encode(Ts &&... aArgs) const
102102
{
103103
return mAttributeValueEncoder.EncodeListItem(std::forward<Ts>(aArgs)...);
104104
}
@@ -152,7 +152,7 @@ class AttributeValueEncoder
152152
* operation.
153153
*/
154154
template <typename... Ts>
155-
CHIP_ERROR Encode(Ts... aArgs)
155+
CHIP_ERROR Encode(Ts &&... aArgs)
156156
{
157157
mTriedEncode = true;
158158
return EncodeAttributeReportIB(std::forward<Ts>(aArgs)...);
@@ -209,7 +209,7 @@ class AttributeValueEncoder
209209
friend class ListEncodeHelper;
210210

211211
template <typename... Ts>
212-
CHIP_ERROR EncodeListItem(Ts... aArgs)
212+
CHIP_ERROR EncodeListItem(Ts &&... aArgs)
213213
{
214214
// EncodeListItem must be called after EncodeEmptyList(), thus mCurrentEncodingListIndex and
215215
// mEncodeState.mCurrentEncodingListIndex are not invalid values.
@@ -242,7 +242,7 @@ class AttributeValueEncoder
242242
* Actual logic for encoding a single AttributeReportIB in AttributeReportIBs.
243243
*/
244244
template <typename... Ts>
245-
CHIP_ERROR EncodeAttributeReportIB(Ts... aArgs)
245+
CHIP_ERROR EncodeAttributeReportIB(Ts &&... aArgs)
246246
{
247247
mTriedEncode = true;
248248
AttributeReportBuilder builder;

src/app/BUILD.gn

+1
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ static_library("app") {
139139

140140
public_deps = [
141141
":app_buildconfig",
142+
"${chip_root}/src/access",
142143
"${chip_root}/src/app/util:device_callbacks_manager",
143144
"${chip_root}/src/lib/support",
144145
"${chip_root}/src/messaging",

0 commit comments

Comments
 (0)