16
16
*/
17
17
18
18
#include < app/clusters/scenes-server/SceneHandlerImpl.h>
19
+ #include < app/util/ember-io-storage.h>
19
20
#include < app/util/endpoint-config-api.h>
20
21
#include < app/util/odd-sized-integers.h>
21
22
@@ -37,7 +38,7 @@ template <typename Type>
37
38
typename app::NumericAttributeTraits<Type>::WorkingType
38
39
ConvertDefaultValueToWorkingValue (const EmberAfDefaultAttributeValue & defaultValue)
39
40
{
40
- if (sizeof (typename app::NumericAttributeTraits<Type>::WorkingType) <= 2 )
41
+ if constexpr (sizeof (typename app::NumericAttributeTraits<Type>::WorkingType) <= 2 )
41
42
{
42
43
return static_cast <typename app::NumericAttributeTraits<Type>::WorkingType>(defaultValue.defaultValue );
43
44
}
@@ -47,11 +48,11 @@ ConvertDefaultValueToWorkingValue(const EmberAfDefaultAttributeValue & defaultVa
47
48
return app::NumericAttributeTraits<Type>::StorageToWorking (sValue );
48
49
}
49
50
50
- // / IsOnlyOneValuePopulated
51
- // / @brief Helper function to verify if only one value is populated in a given AttributeValuePairType
51
+ // / IsExactlyOneValuePopulated
52
+ // / @brief Helper function to verify that exactly one value is populated in a given AttributeValuePairType
52
53
// / @param AttributeValuePairType & type AttributeValuePairType to verify
53
54
// / @return bool true if only one value is populated, false otherwise
54
- bool IsOnlyOneValuePopulated (const AttributeValuePairType & type)
55
+ bool IsExactlyOneValuePopulated (const AttributeValuePairType & type)
55
56
{
56
57
int count = 0 ;
57
58
if (type.valueUnsigned8 .HasValue ())
@@ -73,14 +74,14 @@ bool IsOnlyOneValuePopulated(const AttributeValuePairType & type)
73
74
return count == 1 ;
74
75
}
75
76
76
- // / CapAttributeID
77
+ // / CapAttributeValue
77
78
// / Cap the attribute value based on the attribute's min and max if they are defined,
78
79
// / or based on the attribute's size if they are not.
79
80
// / @param[in] aVPair AttributeValuePairType
80
81
// / @param[in] metadata EmberAfAttributeMetadata
81
82
// /
82
83
template <typename Type>
83
- void CapAttributeID (typename app::NumericAttributeTraits<Type>::WorkingType & Value , const EmberAfAttributeMetadata * metadata)
84
+ void CapAttributeValue (typename app::NumericAttributeTraits<Type>::WorkingType & value , const EmberAfAttributeMetadata * metadata)
84
85
{
85
86
using IntType = app::NumericAttributeTraits<Type>;
86
87
using WorkingType = typename IntType::WorkingType;
@@ -89,7 +90,10 @@ void CapAttributeID(typename app::NumericAttributeTraits<Type>::WorkingType & Va
89
90
WorkingType minValue;
90
91
uint16_t bitWidth = static_cast <uint16_t >(emberAfAttributeSize (metadata) * 8 );
91
92
92
- // Min/Max Value capps for the OddSize integers
93
+ // TODO Use min/max values from Type to obtain min/max instead of relying on metadata. See:
94
+ // https://github.com/project-chip/connectedhomeip/issues/35328
95
+
96
+ // Min/Max Value caps for the OddSize integers
93
97
if (metadata->IsSignedIntegerAttribute ())
94
98
{
95
99
// We use emberAfAttributeSize for cases like INT24S, INT40S, INT48S, INT56S where numeric_limits<WorkingType>::max()
@@ -101,7 +105,7 @@ void CapAttributeID(typename app::NumericAttributeTraits<Type>::WorkingType & Va
101
105
{
102
106
// We use emberAfAttributeSize for cases like INT24U, INT40U, INT48U, INT56U where numeric_limits<WorkingType>::max()
103
107
// wouldn't work
104
- if (ZCL_INT64U_ATTRIBUTE_TYPE == metadata->attributeType )
108
+ if (ZCL_INT64U_ATTRIBUTE_TYPE == app::Compatibility::Internal::AttributeBaseType ( metadata->attributeType ) )
105
109
{
106
110
maxValue = static_cast <WorkingType>(UINT64_MAX); // Bit shift of 64 is undefined so we use UINT64_MAX
107
111
}
@@ -118,7 +122,7 @@ void CapAttributeID(typename app::NumericAttributeTraits<Type>::WorkingType & Va
118
122
if (metadata->IsBoolean ())
119
123
{
120
124
// Caping the value to 1 in case values greater than 1 are set
121
- Value = Value ? 1 : 0 ;
125
+ value = value ? 1 : 0 ;
122
126
return ;
123
127
}
124
128
@@ -130,13 +134,20 @@ void CapAttributeID(typename app::NumericAttributeTraits<Type>::WorkingType & Va
130
134
maxValue = ConvertDefaultValueToWorkingValue<Type>(minMaxValue->maxValue );
131
135
}
132
136
133
- if (minValue > Value)
137
+ if (metadata->IsNullable () && (minValue > value || maxValue < value))
138
+ {
139
+ // If the attribute is nullable, the value can be set to NULL
140
+ app::NumericAttributeTraits<WorkingType>::SetNull (value);
141
+ return ;
142
+ }
143
+
144
+ if (minValue > value)
134
145
{
135
- Value = minValue;
146
+ value = minValue;
136
147
}
137
- else if (maxValue < Value )
148
+ else if (maxValue < value )
138
149
{
139
- Value = maxValue;
150
+ value = maxValue;
140
151
}
141
152
}
142
153
@@ -159,72 +170,74 @@ CHIP_ERROR ValidateAttributePath(EndpointId endpoint, ClusterId cluster, Attribu
159
170
}
160
171
161
172
// There should never be more than one populated value in an ExtensionFieldSet
162
- VerifyOrReturnError (IsOnlyOneValuePopulated (aVPair), CHIP_ERROR_INVALID_ARGUMENT);
173
+ VerifyOrReturnError (IsExactlyOneValuePopulated (aVPair), CHIP_ERROR_INVALID_ARGUMENT);
163
174
164
- switch (metadata->attributeType )
175
+ switch (app::Compatibility::Internal::AttributeBaseType ( metadata->attributeType ) )
165
176
{
166
177
case ZCL_BOOLEAN_ATTRIBUTE_TYPE:
167
- case ZCL_BITMAP8_ATTRIBUTE_TYPE:
168
- case ZCL_ENUM8_ATTRIBUTE_TYPE:
169
178
case ZCL_INT8U_ATTRIBUTE_TYPE:
170
179
VerifyOrReturnError (aVPair.valueUnsigned8 .HasValue (), CHIP_ERROR_INVALID_ARGUMENT);
171
- CapAttributeID <uint8_t >(aVPair.valueUnsigned8 .Value (), metadata);
180
+ CapAttributeValue <uint8_t >(aVPair.valueUnsigned8 .Value (), metadata);
172
181
break ;
173
- case ZCL_BITMAP16_ATTRIBUTE_TYPE:
174
- case ZCL_ENUM16_ATTRIBUTE_TYPE:
175
182
case ZCL_INT16U_ATTRIBUTE_TYPE:
176
183
VerifyOrReturnError (aVPair.valueUnsigned16 .HasValue (), CHIP_ERROR_INVALID_ARGUMENT);
177
- CapAttributeID <uint16_t >(aVPair.valueUnsigned16 .Value (), metadata);
184
+ CapAttributeValue <uint16_t >(aVPair.valueUnsigned16 .Value (), metadata);
178
185
break ;
179
186
case ZCL_INT24U_ATTRIBUTE_TYPE:
180
187
VerifyOrReturnError (aVPair.valueUnsigned32 .HasValue (), CHIP_ERROR_INVALID_ARGUMENT);
181
- CapAttributeID <OddSizedInteger<3 , false >>(aVPair.valueUnsigned32 .Value (), metadata);
188
+ CapAttributeValue <OddSizedInteger<3 , false >>(aVPair.valueUnsigned32 .Value (), metadata);
182
189
break ;
183
- case ZCL_BITMAP32_ATTRIBUTE_TYPE:
184
190
case ZCL_INT32U_ATTRIBUTE_TYPE:
185
191
VerifyOrReturnError (aVPair.valueUnsigned32 .HasValue (), CHIP_ERROR_INVALID_ARGUMENT);
186
- CapAttributeID<uint32_t >(aVPair.valueUnsigned32 .Value (), metadata);
192
+ CapAttributeValue<uint32_t >(aVPair.valueUnsigned32 .Value (), metadata);
193
+ break ;
194
+ case ZCL_INT40U_ATTRIBUTE_TYPE:
195
+ VerifyOrReturnError (aVPair.valueUnsigned64 .HasValue (), CHIP_ERROR_INVALID_ARGUMENT);
196
+ CapAttributeValue<OddSizedInteger<5 , false >>(aVPair.valueUnsigned64 .Value (), metadata);
187
197
break ;
188
198
case ZCL_INT48U_ATTRIBUTE_TYPE:
189
199
VerifyOrReturnError (aVPair.valueUnsigned64 .HasValue (), CHIP_ERROR_INVALID_ARGUMENT);
190
- CapAttributeID <OddSizedInteger<6 , false >>(aVPair.valueUnsigned64 .Value (), metadata);
200
+ CapAttributeValue <OddSizedInteger<6 , false >>(aVPair.valueUnsigned64 .Value (), metadata);
191
201
break ;
192
202
case ZCL_INT56U_ATTRIBUTE_TYPE:
193
203
VerifyOrReturnError (aVPair.valueUnsigned64 .HasValue (), CHIP_ERROR_INVALID_ARGUMENT);
194
- CapAttributeID <OddSizedInteger<7 , false >>(aVPair.valueUnsigned64 .Value (), metadata);
204
+ CapAttributeValue <OddSizedInteger<7 , false >>(aVPair.valueUnsigned64 .Value (), metadata);
195
205
break ;
196
- case ZCL_BITMAP64_ATTRIBUTE_TYPE:
197
206
case ZCL_INT64U_ATTRIBUTE_TYPE:
198
207
VerifyOrReturnError (aVPair.valueUnsigned64 .HasValue (), CHIP_ERROR_INVALID_ARGUMENT);
199
- CapAttributeID <uint64_t >(aVPair.valueUnsigned64 .Value (), metadata);
208
+ CapAttributeValue <uint64_t >(aVPair.valueUnsigned64 .Value (), metadata);
200
209
break ;
201
210
case ZCL_INT8S_ATTRIBUTE_TYPE:
202
211
VerifyOrReturnError (aVPair.valueSigned8 .HasValue (), CHIP_ERROR_INVALID_ARGUMENT);
203
- CapAttributeID <int8_t >(aVPair.valueSigned8 .Value (), metadata);
212
+ CapAttributeValue <int8_t >(aVPair.valueSigned8 .Value (), metadata);
204
213
break ;
205
214
case ZCL_INT16S_ATTRIBUTE_TYPE:
206
215
VerifyOrReturnError (aVPair.valueSigned16 .HasValue (), CHIP_ERROR_INVALID_ARGUMENT);
207
- CapAttributeID <int16_t >(aVPair.valueSigned16 .Value (), metadata);
216
+ CapAttributeValue <int16_t >(aVPair.valueSigned16 .Value (), metadata);
208
217
break ;
209
218
case ZCL_INT24S_ATTRIBUTE_TYPE:
210
219
VerifyOrReturnError (aVPair.valueSigned32 .HasValue (), CHIP_ERROR_INVALID_ARGUMENT);
211
- CapAttributeID <OddSizedInteger<3 , true >>(aVPair.valueSigned32 .Value (), metadata);
220
+ CapAttributeValue <OddSizedInteger<3 , true >>(aVPair.valueSigned32 .Value (), metadata);
212
221
break ;
213
222
case ZCL_INT32S_ATTRIBUTE_TYPE:
214
223
VerifyOrReturnError (aVPair.valueSigned32 .HasValue (), CHIP_ERROR_INVALID_ARGUMENT);
215
- CapAttributeID<int32_t >(aVPair.valueSigned32 .Value (), metadata);
224
+ CapAttributeValue<int32_t >(aVPair.valueSigned32 .Value (), metadata);
225
+ break ;
226
+ case ZCL_INT40S_ATTRIBUTE_TYPE:
227
+ VerifyOrReturnError (aVPair.valueSigned64 .HasValue (), CHIP_ERROR_INVALID_ARGUMENT);
228
+ CapAttributeValue<OddSizedInteger<5 , true >>(aVPair.valueSigned64 .Value (), metadata);
216
229
break ;
217
230
case ZCL_INT48S_ATTRIBUTE_TYPE:
218
231
VerifyOrReturnError (aVPair.valueSigned64 .HasValue (), CHIP_ERROR_INVALID_ARGUMENT);
219
- CapAttributeID <OddSizedInteger<6 , true >>(aVPair.valueSigned64 .Value (), metadata);
232
+ CapAttributeValue <OddSizedInteger<6 , true >>(aVPair.valueSigned64 .Value (), metadata);
220
233
break ;
221
234
case ZCL_INT56S_ATTRIBUTE_TYPE:
222
235
VerifyOrReturnError (aVPair.valueSigned64 .HasValue (), CHIP_ERROR_INVALID_ARGUMENT);
223
- CapAttributeID <OddSizedInteger<7 , true >>(aVPair.valueSigned64 .Value (), metadata);
236
+ CapAttributeValue <OddSizedInteger<7 , true >>(aVPair.valueSigned64 .Value (), metadata);
224
237
break ;
225
238
case ZCL_INT64S_ATTRIBUTE_TYPE:
226
239
VerifyOrReturnError (aVPair.valueSigned64 .HasValue (), CHIP_ERROR_INVALID_ARGUMENT);
227
- CapAttributeID <int64_t >(aVPair.valueSigned64 .Value (), metadata);
240
+ CapAttributeValue <int64_t >(aVPair.valueSigned64 .Value (), metadata);
228
241
break ;
229
242
default :
230
243
return CHIP_IM_GLOBAL_STATUS (UnsupportedAttribute);
0 commit comments