Skip to content

Commit 5533f4d

Browse files
authored
Clean up the redundant user labels when the list becomes smaller than previous list for a given endpoint (#21336)
* Clean up unused UserLabel after it is not in use * Conduct user label cleanup in the user label cluster
1 parent e260b9e commit 5533f4d

File tree

8 files changed

+289
-37
lines changed

8 files changed

+289
-37
lines changed

examples/providers/DeviceInfoProviderImpl.cpp

+7
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,13 @@ CHIP_ERROR DeviceInfoProviderImpl::SetUserLabelAt(EndpointId endpoint, size_t in
149149
static_cast<uint16_t>(writer.GetLengthWritten()));
150150
}
151151

152+
CHIP_ERROR DeviceInfoProviderImpl::DeleteUserLabelAt(EndpointId endpoint, size_t index)
153+
{
154+
DefaultStorageKeyAllocator keyAlloc;
155+
156+
return mStorage->SyncDeleteKeyValue(keyAlloc.UserLabelIndexKey(endpoint, index));
157+
}
158+
152159
DeviceInfoProvider::UserLabelIterator * DeviceInfoProviderImpl::IterateUserLabel(EndpointId endpoint)
153160
{
154161
return chip::Platform::New<UserLabelIteratorImpl>(*this, endpoint);

examples/providers/DeviceInfoProviderImpl.h

+1
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ class DeviceInfoProviderImpl : public DeviceInfoProvider
9797
CHIP_ERROR SetUserLabelLength(EndpointId endpoint, size_t val) override;
9898
CHIP_ERROR GetUserLabelLength(EndpointId endpoint, size_t & val) override;
9999
CHIP_ERROR SetUserLabelAt(EndpointId endpoint, size_t index, const UserLabelType & userLabel) override;
100+
CHIP_ERROR DeleteUserLabelAt(EndpointId endpoint, size_t index) override;
100101

101102
private:
102103
static constexpr size_t UserLabelTLVMaxSize() { return TLV::EstimateStructOverhead(kMaxLabelNameLength, kMaxLabelValueLength); }

src/app/clusters/user-label-server/user-label-server.cpp

+34
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@
2525
#include <app-common/zap-generated/ids/Attributes.h>
2626
#include <app-common/zap-generated/ids/Clusters.h>
2727
#include <app/AttributeAccessInterface.h>
28+
#include <app/server/Server.h>
2829
#include <app/util/attribute-storage.h>
30+
#include <credentials/FabricTable.h>
2931
#include <lib/support/CodeUtils.h>
3032
#include <lib/support/logging/CHIPLogging.h>
3133
#include <platform/DeviceInfoProvider.h>
@@ -184,7 +186,39 @@ CHIP_ERROR UserLabelAttrAccess::Write(const ConcreteDataAttributePath & aPath, A
184186

185187
} // anonymous namespace
186188

189+
class UserLabelFabricTableDelegate : public chip::FabricTable::Delegate
190+
{
191+
public:
192+
// Gets called when a fabric is deleted
193+
void OnFabricRemoved(const FabricTable & fabricTable, FabricIndex fabricIndex) override
194+
{
195+
// If the FabricIndex matches the last remaining entry in the Fabrics list, then the device SHALL delete all Matter
196+
// related data on the node which was created since it was commissioned.
197+
if (Server::GetInstance().GetFabricTable().FabricCount() == 0)
198+
{
199+
ChipLogProgress(Zcl, "UserLabel: Last Fabric index 0x%x was removed", static_cast<unsigned>(fabricIndex));
200+
201+
// Delete all user label data on the node which was added since it was commissioned.
202+
DeviceLayer::DeviceInfoProvider * provider = DeviceLayer::GetDeviceInfoProvider();
203+
if (provider)
204+
{
205+
for (auto endpoint : EnabledEndpointsWithServerCluster(UserLabel::Id))
206+
{
207+
// If UserLabel cluster is implemented on this endpoint
208+
if (CHIP_NO_ERROR != provider->ClearUserLabelList(endpoint))
209+
{
210+
ChipLogError(Zcl, "UserLabel::Failed to clear UserLabelList for endpoint:%d", endpoint);
211+
}
212+
}
213+
}
214+
}
215+
}
216+
};
217+
218+
UserLabelFabricTableDelegate gUserLabelFabricDelegate;
219+
187220
void MatterUserLabelPluginServerInitCallback(void)
188221
{
189222
registerAttributeAccessOverride(&gAttrAccess);
223+
Server::GetInstance().GetFabricTable().AddFabricDelegate(&gUserLabelFabricDelegate);
190224
}

src/app/tests/suites/TestUserLabelCluster.yaml

+25-1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,30 @@ tests:
2828
- name: "nodeId"
2929
value: nodeId
3030

31+
- label: "Commit User Label List"
32+
command: "writeAttribute"
33+
attribute: "label list"
34+
arguments:
35+
value:
36+
[
37+
{ label: "room", value: "bedroom 1" },
38+
{ label: "orientation", value: "South" },
39+
{ label: "floor", value: "2" },
40+
{ label: "direction", value: "down" },
41+
]
42+
43+
- label: "Verify committed User Label List"
44+
command: "readAttribute"
45+
attribute: "label list"
46+
response:
47+
value:
48+
[
49+
{ label: "room", value: "bedroom 1" },
50+
{ label: "orientation", value: "South" },
51+
{ label: "floor", value: "2" },
52+
{ label: "direction", value: "down" },
53+
]
54+
3155
- label: "Clear User Label List"
3256
command: "writeAttribute"
3357
attribute: "label list"
@@ -64,7 +88,7 @@ tests:
6488
- name: "nodeId"
6589
value: nodeId
6690

67-
- label: "Verify"
91+
- label: "Verify User Label List after reboot"
6892
command: "readAttribute"
6993
attribute: "label list"
7094
response:

src/include/platform/DeviceInfoProvider.h

+11
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ class DeviceInfoProvider
9090
void SetStorageDelegate(PersistentStorageDelegate * storage);
9191

9292
CHIP_ERROR SetUserLabelList(EndpointId endpoint, const AttributeList<UserLabelType, kMaxUserLabelListLength> & labelList);
93+
CHIP_ERROR ClearUserLabelList(EndpointId endpoint);
9394
CHIP_ERROR AppendUserLabel(EndpointId endpoint, const UserLabelType & label);
9495

9596
// Iterators
@@ -133,6 +134,16 @@ class DeviceInfoProvider
133134
*/
134135
virtual CHIP_ERROR SetUserLabelAt(EndpointId endpoint, size_t index, const UserLabelType & userLabel) = 0;
135136

137+
/**
138+
* @brief Delete the UserLabel at the specified index of the UserLabelList on a given endpoint
139+
*
140+
* @param endpoint - id to UserLabelList on which to delete the UserLabel.
141+
* @param index - index within the UserLabelList for which to remove the UserLabel.
142+
* @return CHIP_NO_ERROR on success, CHIP_ERROR_INVALID_KEY_ID if index exceed the range (Total length - 1),
143+
* or other CHIP_ERROR values from implementation on other errors.
144+
*/
145+
virtual CHIP_ERROR DeleteUserLabelAt(EndpointId endpoint, size_t index) = 0;
146+
136147
/**
137148
* @brief Set the total length of the UserLabelList on a given endpoint
138149
*

src/platform/DeviceInfoProvider.cpp

+30-2
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,43 @@ DeviceInfoProvider * gDeviceInfoProvider = nullptr;
3838
CHIP_ERROR DeviceInfoProvider::SetUserLabelList(EndpointId endpoint,
3939
const AttributeList<UserLabelType, kMaxUserLabelListLength> & labelList)
4040
{
41-
size_t index = 0;
41+
size_t index = 0;
42+
size_t previousLength = 0;
43+
size_t currentLength = labelList.size();
4244

43-
ReturnErrorOnFailure(SetUserLabelLength(endpoint, labelList.size()));
45+
CHIP_ERROR err = GetUserLabelLength(endpoint, previousLength);
46+
VerifyOrReturnError(err == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND || err == CHIP_NO_ERROR, err);
47+
48+
ReturnErrorOnFailure(SetUserLabelLength(endpoint, currentLength));
4449

4550
for (const UserLabelType & label : labelList)
4651
{
4752
ReturnErrorOnFailure(SetUserLabelAt(endpoint, index++, label));
4853
}
4954

55+
// If the list becomes smaller than previous list for a given endpoint, all "over-size" keys
56+
// (keys for [current_length..previous_length-1]) should be deleted, to recover space.
57+
for (size_t i = currentLength; i < previousLength; i++)
58+
{
59+
ReturnErrorOnFailure(DeleteUserLabelAt(endpoint, i));
60+
}
61+
62+
return CHIP_NO_ERROR;
63+
}
64+
65+
CHIP_ERROR DeviceInfoProvider::ClearUserLabelList(EndpointId endpoint)
66+
{
67+
size_t length;
68+
69+
CHIP_ERROR err = GetUserLabelLength(endpoint, length);
70+
VerifyOrReturnError(err != CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND, CHIP_NO_ERROR);
71+
ReturnErrorOnFailure(err);
72+
73+
for (size_t i = 0; i < length; i++)
74+
{
75+
ReturnErrorOnFailure(DeleteUserLabelAt(endpoint, i));
76+
}
77+
5078
return CHIP_NO_ERROR;
5179
}
5280

zzz_generated/chip-tool/zap-generated/test/Commands.h

+75-14
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)