|
16 | 16 | */
|
17 | 17 |
|
18 | 18 | #include <app/clusters/scenes-server/SceneHandlerImpl.h>
|
| 19 | +#include <app/util/endpoint-config-api.h> |
19 | 20 |
|
20 | 21 | namespace chip {
|
21 | 22 | namespace scenes {
|
22 | 23 |
|
23 | 24 | namespace {
|
24 | 25 |
|
25 |
| -/// ValideAttribute |
| 26 | +using ConcreteAttributePath = app::ConcreteAttributePath; |
| 27 | +using AttributeValuePairType = app::Clusters::ScenesManagement::Structs::AttributeValuePair::Type; |
| 28 | + |
| 29 | +/// CapAttributeID |
| 30 | +/// Cap the attribute value based on the attribute type size |
| 31 | +/// @param[in] aVPair AttributeValuePairType |
| 32 | +/// @param[in] metadata EmberAfAttributeMetadata |
| 33 | +/// |
| 34 | +void CapAttributeID(AttributeValuePairType & aVPair, const EmberAfAttributeMetadata * metadata) |
| 35 | +{ |
| 36 | + // Calculate the maximum value that can be represented with the given number of bytes |
| 37 | + uint64_t maxValue = (1ULL << (metadata->size * 8)) - 1; |
| 38 | + |
| 39 | + // If the attribute ID is greater than the maximum value, cap it |
| 40 | + if (aVPair.attributeValue > maxValue) |
| 41 | + { |
| 42 | + aVPair.attributeValue = maxValue; |
| 43 | + } |
| 44 | +} |
| 45 | + |
26 | 46 | /// @brief Validate the attribute exists for a given cluster
|
| 47 | +/// @param[in] endpoint Endpoint ID |
27 | 48 | /// @param[in] clusterID Cluster ID
|
28 |
| -/// @param[in] attID Attribute ID |
| 49 | +/// @param[in] aVPair AttributeValuePairType, will be mutated to cap the value if it is out of range |
29 | 50 | /// @return CHIP_ERROR_UNSUPPORTED_ATTRIBUTE if the attribute does not exist for a given cluster or is not scenable
|
30 | 51 | /// @note This will allways fail for global list attributes. If we do want to make them scenable someday, we will need to
|
31 | 52 | /// use a different validation method.
|
32 |
| -// TODO: Assess if we also want to throw an error if the attribute value is out of range |
| 53 | +// TODO: Assess if (and how) we also want to throw an error if the attribute value is out of range |
33 | 54 | // TODO: Add check for "S" quality to determine if the attribute is scenable once suported :
|
34 | 55 | // https://github.com/project-chip/connectedhomeip/issues/24177
|
35 |
| -CHIP_ERROR ValidateAttributePath(EndpointId endpoint, ClusterId cluster, AttributeId attributeId) |
| 56 | +CHIP_ERROR ValidateAttributePath(EndpointId endpoint, ClusterId cluster, AttributeValuePairType & aVPair) |
36 | 57 | {
|
37 |
| - bool attIndex = emberAfContainsAttribute(endpoint, cluster, attributeId); |
| 58 | + bool attIndex = emberAfContainsAttribute(endpoint, cluster, aVPair.attributeID); |
38 | 59 | if (!attIndex)
|
39 | 60 | {
|
40 | 61 | return CHIP_ERROR_UNSUPPORTED_ATTRIBUTE;
|
41 | 62 | }
|
| 63 | + |
| 64 | + EmberAfAttributeMetadata metadata = *emberAfLocateAttributeMetadata(endpoint, cluster, aVPair.attributeID); |
| 65 | + |
| 66 | + // Cap value based on the attribute type size |
| 67 | + CapAttributeID(aVPair, &metadata); |
| 68 | + |
42 | 69 | return CHIP_NO_ERROR;
|
43 | 70 | }
|
44 | 71 | } // namespace
|
@@ -81,8 +108,9 @@ DefaultSceneHandlerImpl::SerializeAdd(EndpointId endpoint, const ExtensionFieldS
|
81 | 108 | auto pair_iterator = extensionFieldSet.attributeValueList.begin();
|
82 | 109 | while (pair_iterator.Next())
|
83 | 110 | {
|
84 |
| - ReturnErrorOnFailure(ValidateAttributePath(endpoint, extensionFieldSet.clusterID, pair_iterator.GetValue().attributeID)); |
85 |
| - aVPairs[pairCount] = pair_iterator.GetValue(); |
| 111 | + AttributeValuePairType currentPair = pair_iterator.GetValue(); |
| 112 | + ReturnErrorOnFailure(ValidateAttributePath(endpoint, extensionFieldSet.clusterID, currentPair)); |
| 113 | + aVPairs[pairCount] = currentPair; |
86 | 114 | pairCount++;
|
87 | 115 | }
|
88 | 116 | ReturnErrorOnFailure(pair_iterator.GetStatus());
|
|
0 commit comments