blob: 5be6916438d48a7386dfc9df0ef752ad8e2ca944 [file] [log] [blame]
/**
*
* 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 <app-common/zap-generated/attribute-type.h>
#include <app/util/basic-types.h>
#include <cstdint>
/**
* @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 { return attributeType == ZCL_BOOLEAN_ATTRIBUTE_TYPE; }
/**
* Check wether this attribute is signed based on its type according to the spec.
*/
bool IsSignedIntegerAttribute() const { return chip::app::IsSignedAttributeType(attributeType); }
/**
* 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);