Skip to content

Commit 0e88d65

Browse files
Optimize codesize so the cost of passing the MarkAttributeDirty argument is paid only by those who neeed it.
1 parent 8a600be commit 0e88d65

File tree

5 files changed

+10796
-2312
lines changed

5 files changed

+10796
-2312
lines changed

src/app/util/af.h

+14-4
Original file line numberDiff line numberDiff line change
@@ -96,10 +96,20 @@ bool emberAfContainsClient(chip::EndpointId endpoint, chip::ClusterId clusterId)
9696
* data type (as Accessors.h/cpp have this correct by default).
9797
* TODO: this not checking seems off - what if this is run without Accessors.h ?
9898
*/
99-
chip::Protocols::InteractionModel::Status
100-
emberAfWriteAttribute(chip::EndpointId endpoint, chip::ClusterId cluster, chip::AttributeId attributeID, uint8_t * dataPtr,
101-
EmberAfAttributeType dataType,
102-
chip::app::MarkAttributeDirty markDirty = chip::app::MarkAttributeDirty::kIfChanged);
99+
chip::Protocols::InteractionModel::Status emberAfWriteAttribute(chip::EndpointId endpoint, chip::ClusterId cluster,
100+
chip::AttributeId attributeID, uint8_t * dataPtr,
101+
EmberAfAttributeType dataType);
102+
103+
/**
104+
* A version of emberAfWriteAttribute that allows controlling when the attribute
105+
* should be marked dirty. This is an overload, not an optional argument, to
106+
* reduce codesize at all the callsites that want to write without doing
107+
* anything special to control the dirty marking.
108+
*/
109+
chip::Protocols::InteractionModel::Status emberAfWriteAttribute(chip::EndpointId endpoint, chip::ClusterId cluster,
110+
chip::AttributeId attributeID, uint8_t * dataPtr,
111+
EmberAfAttributeType dataType,
112+
chip::app::MarkAttributeDirty markDirty);
103113

104114
/**
105115
* @brief Read the attribute value, performing all the checks.

src/app/util/attribute-table.cpp

+46-3
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,53 @@ using chip::Protocols::InteractionModel::Status;
3131
using namespace chip;
3232
using namespace chip::app;
3333

34+
namespace {
35+
/**
36+
* @brief write an attribute, performing all the checks.
37+
*
38+
* This function will attempt to write the attribute value from
39+
* the provided pointer. This function will only check that the
40+
* attribute exists. If it does it will write the value into
41+
* the attribute table for the given attribute.
42+
*
43+
* This function will not check to see if the attribute is
44+
* writable since the read only / writable characteristic
45+
* of an attribute only pertains to external devices writing
46+
* over the air. Because this function is being called locally
47+
* it assumes that the device knows what it is doing and has permission
48+
* to perform the given operation.
49+
*
50+
* if true is passed in for overrideReadOnlyAndDataType then the data type is
51+
* not checked and the read-only flag is ignored. This mode is meant for
52+
* testing or setting the initial value of the attribute on the device.
53+
*
54+
* this returns:
55+
* - Status::UnsupportedEndpoint: if endpoint isn't supported by the device.
56+
* - Status::UnsupportedCluster: if cluster isn't supported on the endpoint.
57+
* - Status::UnsupportedAttribute: if attribute isn't supported in the cluster.
58+
* - Status::InvalidDataType: if the data type passed in doesnt match the type
59+
* stored in the attribute table
60+
* - Status::UnsupportedWrite: if the attribute isnt writable
61+
* - Status::ConstraintError: if the value is set out of the allowable range for
62+
* the attribute
63+
* - Status::Success: if the attribute was found and successfully written
64+
*/
65+
Status emAfWriteAttribute(EndpointId endpoint, ClusterId cluster, AttributeId attributeID, uint8_t * data,
66+
EmberAfAttributeType dataType, bool overrideReadOnlyAndDataType, MarkAttributeDirty markDirty);
67+
} // anonymous namespace
68+
3469
Status emAfWriteAttributeExternal(EndpointId endpoint, ClusterId cluster, AttributeId attributeID, uint8_t * dataPtr,
3570
EmberAfAttributeType dataType)
3671
{
37-
return emAfWriteAttribute(endpoint, cluster, attributeID, dataPtr, dataType, false /* override read-only */);
72+
return emAfWriteAttribute(endpoint, cluster, attributeID, dataPtr, dataType, false /* override read-only */,
73+
MarkAttributeDirty::kIfChanged);
74+
}
75+
76+
Status emberAfWriteAttribute(EndpointId endpoint, ClusterId cluster, AttributeId attributeID, uint8_t * dataPtr,
77+
EmberAfAttributeType dataType)
78+
{
79+
return emAfWriteAttribute(endpoint, cluster, attributeID, dataPtr, dataType, true /* override read-only */,
80+
MarkAttributeDirty::kIfChanged);
3881
}
3982

4083
Status emberAfWriteAttribute(EndpointId endpoint, ClusterId cluster, AttributeId attributeID, uint8_t * dataPtr,
@@ -149,8 +192,6 @@ Status AttributeValueIsChanging(EndpointId endpoint, ClusterId cluster, Attribut
149192
return Status::Success;
150193
}
151194

152-
} // anonymous namespace
153-
154195
Status emAfWriteAttribute(EndpointId endpoint, ClusterId cluster, AttributeId attributeID, uint8_t * data,
155196
EmberAfAttributeType dataType, bool overrideReadOnlyAndDataType, MarkAttributeDirty markDirty)
156197
{
@@ -301,6 +342,8 @@ Status emAfWriteAttribute(EndpointId endpoint, ClusterId cluster, AttributeId at
301342
return Status::Success;
302343
}
303344

345+
} // anonymous namespace
346+
304347
Status emberAfReadAttribute(EndpointId endpoint, ClusterId cluster, AttributeId attributeID, uint8_t * dataPtr, uint16_t readLength)
305348
{
306349
const EmberAfAttributeMetadata * metadata = nullptr;

src/app/util/attribute-table.h

-35
Original file line numberDiff line numberDiff line change
@@ -30,38 +30,3 @@
3030
chip::Protocols::InteractionModel::Status emAfWriteAttributeExternal(chip::EndpointId endpoint, chip::ClusterId cluster,
3131
chip::AttributeId attributeID, uint8_t * dataPtr,
3232
EmberAfAttributeType dataType);
33-
34-
/**
35-
* @brief write an attribute, performing all the checks.
36-
*
37-
* This function will attempt to write the attribute value from
38-
* the provided pointer. This function will only check that the
39-
* attribute exists. If it does it will write the value into
40-
* the attribute table for the given attribute.
41-
*
42-
* This function will not check to see if the attribute is
43-
* writable since the read only / writable characteristic
44-
* of an attribute only pertains to external devices writing
45-
* over the air. Because this function is being called locally
46-
* it assumes that the device knows what it is doing and has permission
47-
* to perform the given operation.
48-
*
49-
* if true is passed in for overrideReadOnlyAndDataType then the data type is
50-
* not checked and the read-only flag is ignored. This mode is meant for
51-
* testing or setting the initial value of the attribute on the device.
52-
*
53-
* this returns:
54-
* - Status::UnsupportedEndpoint: if endpoint isn't supported by the device.
55-
* - Status::UnsupportedCluster: if cluster isn't supported on the endpoint.
56-
* - Status::UnsupportedAttribute: if attribute isn't supported in the cluster.
57-
* - Status::InvalidDataType: if the data type passed in doesnt match the type
58-
* stored in the attribute table
59-
* - Status::UnsupportedWrite: if the attribute isnt writable
60-
* - Status::ConstraintError: if the value is set out of the allowable range for
61-
* the attribute
62-
* - Status::Success: if the attribute was found and successfully written
63-
*/
64-
chip::Protocols::InteractionModel::Status
65-
emAfWriteAttribute(chip::EndpointId endpoint, chip::ClusterId cluster, chip::AttributeId attributeID, uint8_t * data,
66-
EmberAfAttributeType dataType, bool overrideReadOnlyAndDataType,
67-
chip::app::MarkAttributeDirty markDirty = chip::app::MarkAttributeDirty::kIfChanged);

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

+25-11
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,8 @@ Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, {{accessorGet
8686
{{/if}}
8787
}
8888

89-
Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, {{zapTypeToEncodableClusterObjectType type ns=parent.name forceNotNullable=true forceNotOptional=true}} value, MarkAttributeDirty markDirty)
90-
{
89+
{{! Has a passMarkDirty boolean argument that controls which overload of emberAfWriteAttribute we call }}
90+
{{#*inline "setBody"}}
9191
{{~#if (isString type)}}
9292
{{~#*inline "lengthType"}}uint{{#if (isShortString type)}}8{{else}}16{{/if}}_t{{/inline}}
9393
static_assert({{maxLength}} < NumericAttributeTraits<{{>lengthType}}>::kNullValue,
@@ -101,7 +101,7 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, {{zapTypeToEn
101101
Encoding::LittleEndian::Put16(zclString, length);
102102
{{/if}}
103103
memcpy(&zclString[{{>sizingBytes}}], value.data(), value.size());
104-
return emberAfWriteAttribute(endpoint, {{>clusterId}}, Id, zclString, ZCL_{{typeAsDelimitedMacro type}}_ATTRIBUTE_TYPE, markDirty);
104+
return emberAfWriteAttribute(endpoint, {{>clusterId}}, Id, zclString, ZCL_{{typeAsDelimitedMacro type}}_ATTRIBUTE_TYPE{{#if passMarkDirty}}, markDirty{{/if}});
105105
{{else}}
106106
using Traits = NumericAttributeTraits<{{accessorTraitType type}}>;
107107
if (!Traits::CanRepresentValue(/* isNullable = */ {{isNullable}}, value))
@@ -111,33 +111,43 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, {{zapTypeToEn
111111
Traits::StorageType storageValue;
112112
Traits::WorkingToStorage(value, storageValue);
113113
uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
114-
return emberAfWriteAttribute(endpoint, {{>clusterId}}, Id, writable, ZCL_{{typeAsDelimitedMacro type}}_ATTRIBUTE_TYPE, markDirty);
114+
return emberAfWriteAttribute(endpoint, {{>clusterId}}, Id, writable, ZCL_{{typeAsDelimitedMacro type}}_ATTRIBUTE_TYPE{{#if passMarkDirty}}, markDirty{{/if}});
115115
{{/if}}
116+
{{/inline}}
117+
118+
Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, {{zapTypeToEncodableClusterObjectType type ns=parent.name forceNotNullable=true forceNotOptional=true}} value, MarkAttributeDirty markDirty)
119+
{
120+
{{> setBody passMarkDirty=true}}
116121
}
117122

118123
Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, {{zapTypeToEncodableClusterObjectType type ns=parent.name forceNotNullable=true forceNotOptional=true}} value)
119124
{
120-
return Set(endpoint, value, MarkAttributeDirty::kIfChanged);
125+
{{> setBody passMarkDirty=false}}
121126
}
122127

123128
{{#if isNullable}}
124-
Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint, MarkAttributeDirty markDirty)
125-
{
129+
{{! Has a passMarkDirty boolean argument that controls which overload of emberAfWriteAttribute we call }}
130+
{{#*inline "setNullBody"}}
126131
{{#if (isString type)}}
127132
uint8_t zclString[{{>sizingBytes}}] = { {{#if (isShortString type)}}0xFF{{else}}0xFF, 0xFF{{/if}} };
128-
return emberAfWriteAttribute(endpoint, {{>clusterId}}, Id, zclString, ZCL_{{typeAsDelimitedMacro type}}_ATTRIBUTE_TYPE, markDirty);
133+
return emberAfWriteAttribute(endpoint, {{>clusterId}}, Id, zclString, ZCL_{{typeAsDelimitedMacro type}}_ATTRIBUTE_TYPE{{#if passMarkDirty}}, markDirty{{/if}});
129134
{{else}}
130135
using Traits = NumericAttributeTraits<{{accessorTraitType type}}>;
131136
Traits::StorageType value;
132137
Traits::SetNull(value);
133138
uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
134-
return emberAfWriteAttribute(endpoint, {{>clusterId}}, Id, writable, ZCL_{{typeAsDelimitedMacro type}}_ATTRIBUTE_TYPE, markDirty);
139+
return emberAfWriteAttribute(endpoint, {{>clusterId}}, Id, writable, ZCL_{{typeAsDelimitedMacro type}}_ATTRIBUTE_TYPE{{#if passMarkDirty}}, markDirty{{/if}});
135140
{{/if}}
141+
{{/inline}}
142+
143+
Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint, MarkAttributeDirty markDirty)
144+
{
145+
{{> setNullBody passMarkDirty=true}}
136146
}
137147

138148
Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint)
139149
{
140-
return SetNull(endpoint, MarkAttributeDirty::kIfChanged);
150+
{{> setNullBody passMarkDirty=false}}
141151
}
142152

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

152162
Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, {{zapTypeToEncodableClusterObjectType type ns=parent.name isArgument=true forceNotOptional=true}} value)
153163
{
154-
return Set(endpoint, value, MarkAttributeDirty::kIfChanged);
164+
if (value.IsNull()) {
165+
return SetNull(endpoint);
166+
}
167+
168+
return Set(endpoint, value.Value());
155169
}
156170
{{/if}}
157171

0 commit comments

Comments
 (0)