/** * * Copyright (c) 2020 Project CHIP Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include #include /** * @brief Type for referring to ZCL attribute type */ typedef uint8_t EmberAfAttributeType; /** * @brief Type for the attribute mask */ typedef uint8_t EmberAfAttributeMask; /** * @brief Type for default values. * * Default value is either a value itself, if it is 2 bytes or less, * or a pointer to the value itself, if attribute type is longer than * 2 bytes. */ union EmberAfDefaultAttributeValue { constexpr EmberAfDefaultAttributeValue(const uint8_t * ptr) : ptrToDefaultValue(ptr) {} constexpr EmberAfDefaultAttributeValue(uint16_t val) : defaultValue(val) {} /** * Points to data if size is more than 2 bytes. * If size is more than 2 bytes, and this value is NULL, * then the default value is all zeroes. */ const uint8_t * ptrToDefaultValue; /** * Actual default value if the attribute size is 2 bytes or less. */ uint16_t defaultValue; }; /** * @brief Type describing the attribute default, min and max values. * * This struct is required if the attribute mask specifies that this * attribute has a known min and max values. */ typedef struct { /** * Default value of the attribute. */ EmberAfDefaultAttributeValue defaultValue; /** * Minimum allowed value */ EmberAfDefaultAttributeValue minValue; /** * Maximum allowed value. */ EmberAfDefaultAttributeValue maxValue; } EmberAfAttributeMinMaxValue; /** * @brief Union describing the attribute default/min/max values. */ union EmberAfDefaultOrMinMaxAttributeValue { constexpr EmberAfDefaultOrMinMaxAttributeValue(const uint8_t * ptr) : ptrToDefaultValue(ptr) {} constexpr EmberAfDefaultOrMinMaxAttributeValue(uint32_t val) : defaultValue(val) {} constexpr EmberAfDefaultOrMinMaxAttributeValue(const EmberAfAttributeMinMaxValue * ptr) : ptrToMinMaxValue(ptr) {} /** * Points to data if the attribute type is a string or the size of the data is more than 4 bytes. * If the attribute type is a string or the data size is more than 4 bytes, and this value is NULL, * then the default value is all zeroes. */ const uint8_t * ptrToDefaultValue; /** * Actual default value if the attribute is non string and size * is 4 bytes or less. */ uint32_t defaultValue; /** * Points to the min max attribute value structure, if min/max is * supported for this attribute. */ const EmberAfAttributeMinMaxValue * ptrToMinMaxValue; }; // Attribute masks modify how attributes are used by the framework // // Attribute that has this mask is NOT read-only #define ATTRIBUTE_MASK_WRITABLE (0x01) // Attribute that has this mask is saved in non-volatile memory #define ATTRIBUTE_MASK_NONVOLATILE (0x02) // Alias until ZAP gets updated to output ATTRIBUTE_MASK_NONVOLATILE #define ATTRIBUTE_MASK_TOKENIZE ATTRIBUTE_MASK_NONVOLATILE // Attribute that has this mask has a min/max values #define ATTRIBUTE_MASK_MIN_MAX (0x04) // Attribute requires a timed interaction to write #define ATTRIBUTE_MASK_MUST_USE_TIMED_WRITE (0x08) // Attribute deferred to external storage #define ATTRIBUTE_MASK_EXTERNAL_STORAGE (0x10) // Attribute is singleton #define ATTRIBUTE_MASK_SINGLETON (0x20) // Attribute is nullable #define ATTRIBUTE_MASK_NULLABLE (0x40) /** * @brief Each attribute has it's metadata stored in such struct. * * There is only one of these per attribute across all endpoints. */ struct EmberAfAttributeMetadata { /** * Pointer to the default value union. Actual value stored * depends on the mask. */ EmberAfDefaultOrMinMaxAttributeValue defaultValue; /** * Attribute ID, according to ZCL specs. */ chip::AttributeId attributeId; /** * Size of this attribute in bytes. */ uint16_t size; /** * Attribute type, according to ZCL specs. */ EmberAfAttributeType attributeType; /** * Attribute mask, tagging attribute with specific * functionality. */ EmberAfAttributeMask mask; /** * Check wether this attribute is a boolean based on its type according to the spec. */ bool IsBoolean() const; /** * Check wether this attribute is signed based on its type according to the spec. */ bool IsSignedIntegerAttribute() const; /** * Check whether this attribute has a define min and max. */ bool HasMinMax() const { return mask & ATTRIBUTE_MASK_MIN_MAX; } /** * Check whether this attribute is nullable. */ bool IsNullable() const { return mask & ATTRIBUTE_MASK_NULLABLE; } /** * Check whether this attribute is readonly. */ bool IsReadOnly() const { return !(mask & ATTRIBUTE_MASK_WRITABLE); } /** * Check whether this attribute requires a timed write. */ bool MustUseTimedWrite() const { return mask & ATTRIBUTE_MASK_MUST_USE_TIMED_WRITE; } /** * Check whether this attibute's storage is managed outside the built-in * attribute store. */ bool IsExternal() const { return mask & ATTRIBUTE_MASK_EXTERNAL_STORAGE; } /** * Check whether this is a "singleton" attribute, in the sense that it has a * single value across multiple instances of the cluster. This is not * mutually exclusive with the attribute being external. */ bool IsSingleton() const { return mask & ATTRIBUTE_MASK_SINGLETON; } /** * Check whether this attribute is automatically stored in non-volatile * memory. */ bool IsAutomaticallyPersisted() const { return (mask & ATTRIBUTE_MASK_NONVOLATILE) && !IsExternal(); } }; /** @brief Returns true if the given attribute type is a string. */ bool emberAfIsStringAttributeType(EmberAfAttributeType attributeType); /** @brief Returns true if the given attribute type is a long string. */ bool emberAfIsLongStringAttributeType(EmberAfAttributeType attributeType);