Skip to content

Commit 5a1a713

Browse files
Address review comments.
1 parent ca47b59 commit 5a1a713

File tree

9 files changed

+1270
-1237
lines changed

9 files changed

+1270
-1237
lines changed

src/app/util/af-types.h

+12
Original file line numberDiff line numberDiff line change
@@ -297,3 +297,15 @@ typedef chip::Protocols::InteractionModel::Status (*EmberAfClusterPreAttributeCh
297297
#define MAX_INT16U_VALUE (0xFFFF)
298298

299299
/** @} END addtogroup */
300+
301+
namespace chip {
302+
namespace app {
303+
304+
enum class MarkAttributeDirty
305+
{
306+
kIfChanged,
307+
kNo,
308+
};
309+
310+
} // namespace app
311+
} // namespace chip

src/app/util/af.h

+1-2
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424

2525
#include <app/util/af-types.h>
2626

27-
#include <app-common/zap-generated/attributes/Accessors.h>
2827
#include <app/util/endpoint-config-api.h>
2928

3029
#include <lib/core/DataModelTypes.h>
@@ -100,7 +99,7 @@ bool emberAfContainsClient(chip::EndpointId endpoint, chip::ClusterId clusterId)
10099
chip::Protocols::InteractionModel::Status
101100
emberAfWriteAttribute(chip::EndpointId endpoint, chip::ClusterId cluster, chip::AttributeId attributeID, uint8_t * dataPtr,
102101
EmberAfAttributeType dataType,
103-
chip::app::MarkAttributeDirty markDirty = chip::app::MarkAttributeDirty::IfChanged);
102+
chip::app::MarkAttributeDirty markDirty = chip::app::MarkAttributeDirty::kIfChanged);
104103

105104
/**
106105
* @brief Read the attribute value, performing all the checks.

src/app/util/attribute-table.cpp

+58-25
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,55 @@ static bool IsNullValue(const uint8_t * data, uint16_t dataLen, bool isAttribute
102102
return false;
103103
}
104104

105+
namespace {
106+
/**
107+
* Helper function to determine whether the attribute value for the given
108+
* attribute is changing. On success, the isChanging outparam will be set to
109+
* whether the value is changing.
110+
*/
111+
Status AttributeValueIsChanging(EndpointId endpoint, ClusterId cluster, AttributeId attributeID, uint8_t * newValueData,
112+
EmberAfAttributeType dataType, bool * isChanging)
113+
{
114+
size_t valueSize = AttributeTypeSize(dataType);
115+
116+
constexpr size_t maxValueSize = 16; // ipv6adr
117+
if (valueSize > maxValueSize)
118+
{
119+
// Very much unexpected
120+
ChipLogError(Zcl, "Attribute type %d has too-large size %u", dataType, static_cast<unsigned>(valueSize));
121+
return Status::ConstraintError;
122+
}
123+
124+
// valueSize will be 0 when we have no size information for dataType.
125+
// In that case, we can't usefully read the current value, since we
126+
// don't know how big it is.
127+
if (valueSize == 0)
128+
{
129+
// To be safe, claim changing.
130+
*isChanging = true;
131+
return Status::Success;
132+
}
133+
134+
uint8_t oldValueBuffer[maxValueSize];
135+
// Cast to uint16_t is safe, because we checked valueSize <= maxValueSize above.
136+
if (emberAfReadAttribute(endpoint, cluster, attributeID, oldValueBuffer, static_cast<uint16_t>(valueSize)) == Status::Success)
137+
{
138+
if (memcmp(newValueData, oldValueBuffer, valueSize) == 0)
139+
{
140+
// Value has not changed.
141+
*isChanging = false;
142+
return Status::Success;
143+
}
144+
}
145+
146+
// We failed to read the old value, or the value is changing. Either way,
147+
// flag the value as changing to be safe.
148+
*isChanging = true;
149+
return Status::Success;
150+
}
151+
152+
} // anonymous namespace
153+
105154
Status emAfWriteAttribute(EndpointId endpoint, ClusterId cluster, AttributeId attributeID, uint8_t * data,
106155
EmberAfAttributeType dataType, bool overrideReadOnlyAndDataType, MarkAttributeDirty markDirty)
107156
{
@@ -182,40 +231,24 @@ Status emAfWriteAttribute(EndpointId endpoint, ClusterId cluster, AttributeId at
182231
}
183232

184233
// Check whether anything is actually changing, before we do any work here.
185-
size_t valueSize = AttributeTypeSize(dataType);
186-
187-
constexpr size_t maxValueSize = 16; // ipv6adr
188-
if (valueSize > maxValueSize)
234+
bool valueChanging;
235+
Status imStatus = AttributeValueIsChanging(endpoint, cluster, attributeID, data, dataType, &valueChanging);
236+
if (imStatus != Status::Success)
189237
{
190-
// Very much unexpected
191-
ChipLogError(Zcl, "Attribute type %d has too-large size %u", dataType, static_cast<unsigned>(valueSize));
192-
return Status::ConstraintError;
238+
return imStatus;
193239
}
194240

195-
// valueSize will be 0 when we have no size information for dataType.
196-
// In that case, we can't usefully read the current value, since we
197-
// don't know how big it is.
198-
if (valueSize != 0)
241+
if (!valueChanging)
199242
{
200-
uint8_t oldValueBuffer[maxValueSize];
201-
// Cast to uint16_t is safe, because we checked valueSize <= maxValueSize above.
202-
if (emberAfReadAttribute(endpoint, cluster, attributeID, oldValueBuffer, static_cast<uint16_t>(valueSize)) ==
203-
Status::Success)
204-
{
205-
if (memcmp(data, oldValueBuffer, valueSize) == 0)
206-
{
207-
// Value has not changed. Just do nothing.
208-
return Status::Success;
209-
}
210-
}
243+
// Just do nothing.
244+
return Status::Success;
211245
}
212246

213247
const app::ConcreteAttributePath attributePath(endpoint, cluster, attributeID);
214248

215249
// Pre write attribute callback for all attribute changes,
216250
// regardless of cluster.
217-
Protocols::InteractionModel::Status imStatus =
218-
MatterPreAttributeChangeCallback(attributePath, dataType, emberAfAttributeSize(metadata), data);
251+
imStatus = MatterPreAttributeChangeCallback(attributePath, dataType, emberAfAttributeSize(metadata), data);
219252
if (imStatus != Protocols::InteractionModel::Status::Success)
220253
{
221254
return imStatus;
@@ -252,7 +285,7 @@ Status emAfWriteAttribute(EndpointId endpoint, ClusterId cluster, AttributeId at
252285
// The callee will weed out attributes that do not need to be stored.
253286
emAfSaveAttributeToStorageIfNeeded(data, endpoint, cluster, metadata);
254287

255-
if (markDirty != MarkAttributeDirty::No)
288+
if (markDirty != MarkAttributeDirty::kNo)
256289
{
257290
MatterReportingAttributeChangeCallback(endpoint, cluster, attributeID);
258291
}

src/app/util/attribute-table.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -64,4 +64,4 @@ chip::Protocols::InteractionModel::Status emAfWriteAttributeExternal(chip::Endpo
6464
chip::Protocols::InteractionModel::Status
6565
emAfWriteAttribute(chip::EndpointId endpoint, chip::ClusterId cluster, chip::AttributeId attributeID, uint8_t * data,
6666
EmberAfAttributeType dataType, bool overrideReadOnlyAndDataType,
67-
chip::app::MarkAttributeDirty markDirty = chip::app::MarkAttributeDirty::IfChanged);
67+
chip::app::MarkAttributeDirty markDirty = chip::app::MarkAttributeDirty::kIfChanged);

src/app/zap-templates/templates/app/attributes/Accessors-src.zapt

+3-3
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, {{zapTypeToEn
117117

118118
Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, {{zapTypeToEncodableClusterObjectType type ns=parent.name forceNotNullable=true forceNotOptional=true}} value)
119119
{
120-
return Set(endpoint, value, MarkAttributeDirty::IfChanged);
120+
return Set(endpoint, value, MarkAttributeDirty::kIfChanged);
121121
}
122122

123123
{{#if isNullable}}
@@ -137,7 +137,7 @@ Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint, MarkAttri
137137

138138
Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint)
139139
{
140-
return SetNull(endpoint, MarkAttributeDirty::IfChanged);
140+
return SetNull(endpoint, MarkAttributeDirty::kIfChanged);
141141
}
142142

143143
Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, {{zapTypeToEncodableClusterObjectType type ns=parent.name isArgument=true forceNotOptional=true}} value, MarkAttributeDirty markDirty)
@@ -151,7 +151,7 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, {{zapTypeToEn
151151

152152
Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, {{zapTypeToEncodableClusterObjectType type ns=parent.name isArgument=true forceNotOptional=true}} value)
153153
{
154-
return Set(endpoint, value, MarkAttributeDirty::IfChanged);
154+
return Set(endpoint, value, MarkAttributeDirty::kIfChanged);
155155
}
156156
{{/if}}
157157

src/app/zap-templates/templates/app/attributes/Accessors.zapt

-5
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,6 @@
1717
namespace chip {
1818
namespace app {
1919

20-
enum class MarkAttributeDirty {
21-
IfChanged,
22-
No,
23-
};
24-
2520
namespace Clusters {
2621

2722
{{#zcl_clusters}}

zzz_generated/app-common/app-common/zap-generated/attribute-type.cpp

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

0 commit comments

Comments
 (0)