Line data Source code
1 : /**
2 : *
3 : * Copyright (c) 2020 Project CHIP Authors
4 : *
5 : * Licensed under the Apache License, Version 2.0 (the "License");
6 : * you may not use this file except in compliance with the License.
7 : * You may obtain a copy of the License at
8 : *
9 : * http://www.apache.org/licenses/LICENSE-2.0
10 : *
11 : * Unless required by applicable law or agreed to in writing, software
12 : * distributed under the License is distributed on an "AS IS" BASIS,
13 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 : * See the License for the specific language governing permissions and
15 : * limitations under the License.
16 : */
17 :
18 : #pragma once
19 :
20 : #include <app/util/basic-types.h>
21 : #include <cstdint>
22 :
23 : /**
24 : * @brief Type for referring to ZCL attribute type
25 : */
26 : typedef uint8_t EmberAfAttributeType;
27 :
28 : /**
29 : * @brief Type for the attribute mask
30 : */
31 : typedef uint8_t EmberAfAttributeMask;
32 :
33 : /**
34 : * @brief Type for default values.
35 : *
36 : * Default value is either a value itself, if it is 2 bytes or less,
37 : * or a pointer to the value itself, if attribute type is longer than
38 : * 2 bytes.
39 : */
40 : union EmberAfDefaultAttributeValue
41 : {
42 : constexpr EmberAfDefaultAttributeValue(const uint8_t * ptr) : ptrToDefaultValue(ptr) {}
43 : constexpr EmberAfDefaultAttributeValue(uint16_t val) : defaultValue(val) {}
44 :
45 : /**
46 : * Points to data if size is more than 2 bytes.
47 : * If size is more than 2 bytes, and this value is NULL,
48 : * then the default value is all zeroes.
49 : */
50 : const uint8_t * ptrToDefaultValue;
51 :
52 : /**
53 : * Actual default value if the attribute size is 2 bytes or less.
54 : */
55 : uint16_t defaultValue;
56 : };
57 :
58 : /**
59 : * @brief Type describing the attribute default, min and max values.
60 : *
61 : * This struct is required if the attribute mask specifies that this
62 : * attribute has a known min and max values.
63 : */
64 : typedef struct
65 : {
66 : /**
67 : * Default value of the attribute.
68 : */
69 : EmberAfDefaultAttributeValue defaultValue;
70 : /**
71 : * Minimum allowed value
72 : */
73 : EmberAfDefaultAttributeValue minValue;
74 : /**
75 : * Maximum allowed value.
76 : */
77 : EmberAfDefaultAttributeValue maxValue;
78 : } EmberAfAttributeMinMaxValue;
79 :
80 : /**
81 : * @brief Union describing the attribute default/min/max values.
82 : */
83 : union EmberAfDefaultOrMinMaxAttributeValue
84 : {
85 : constexpr EmberAfDefaultOrMinMaxAttributeValue(const uint8_t * ptr) : ptrToDefaultValue(ptr) {}
86 : constexpr EmberAfDefaultOrMinMaxAttributeValue(uint32_t val) : defaultValue(val) {}
87 : constexpr EmberAfDefaultOrMinMaxAttributeValue(const EmberAfAttributeMinMaxValue * ptr) : ptrToMinMaxValue(ptr) {}
88 :
89 : /**
90 : * Points to data if the attribute type is a string or the size of the data is more than 4 bytes.
91 : * If the attribute type is a string or the data size is more than 4 bytes, and this value is NULL,
92 : * then the default value is all zeroes.
93 : */
94 : const uint8_t * ptrToDefaultValue;
95 : /**
96 : * Actual default value if the attribute is non string and size
97 : * is 4 bytes or less.
98 : */
99 : uint32_t defaultValue;
100 : /**
101 : * Points to the min max attribute value structure, if min/max is
102 : * supported for this attribute.
103 : */
104 : const EmberAfAttributeMinMaxValue * ptrToMinMaxValue;
105 : };
106 :
107 : // Attribute masks modify how attributes are used by the framework
108 : //
109 : // Attribute that has this mask is NOT read-only
110 : #define ATTRIBUTE_MASK_WRITABLE (0x01)
111 : // Attribute that has this mask is saved in non-volatile memory
112 : #define ATTRIBUTE_MASK_NONVOLATILE (0x02)
113 : // Alias until ZAP gets updated to output ATTRIBUTE_MASK_NONVOLATILE
114 : #define ATTRIBUTE_MASK_TOKENIZE ATTRIBUTE_MASK_NONVOLATILE
115 : // Attribute that has this mask has a min/max values
116 : #define ATTRIBUTE_MASK_MIN_MAX (0x04)
117 : // Attribute requires a timed interaction to write
118 : #define ATTRIBUTE_MASK_MUST_USE_TIMED_WRITE (0x08)
119 : // Attribute deferred to external storage
120 : #define ATTRIBUTE_MASK_EXTERNAL_STORAGE (0x10)
121 : // Attribute is singleton
122 : #define ATTRIBUTE_MASK_SINGLETON (0x20)
123 : // Attribute is nullable
124 : #define ATTRIBUTE_MASK_NULLABLE (0x40)
125 :
126 : /**
127 : * @brief Each attribute has it's metadata stored in such struct.
128 : *
129 : * There is only one of these per attribute across all endpoints.
130 : */
131 : struct EmberAfAttributeMetadata
132 : {
133 : /**
134 : * Pointer to the default value union. Actual value stored
135 : * depends on the mask.
136 : */
137 : EmberAfDefaultOrMinMaxAttributeValue defaultValue;
138 :
139 : /**
140 : * Attribute ID, according to ZCL specs.
141 : */
142 : chip::AttributeId attributeId;
143 :
144 : /**
145 : * Size of this attribute in bytes.
146 : */
147 : uint16_t size;
148 :
149 : /**
150 : * Attribute type, according to ZCL specs.
151 : */
152 : EmberAfAttributeType attributeType;
153 :
154 : /**
155 : * Attribute mask, tagging attribute with specific
156 : * functionality.
157 : */
158 : EmberAfAttributeMask mask;
159 :
160 : /**
161 : * Check wether this attribute is a boolean based on its type according to the spec.
162 : */
163 : bool IsBoolean() const;
164 :
165 : /**
166 : * Check wether this attribute is signed based on its type according to the spec.
167 : */
168 : bool IsSignedIntegerAttribute() const;
169 :
170 : /**
171 : * Check whether this attribute has a define min and max.
172 : */
173 : bool HasMinMax() const { return mask & ATTRIBUTE_MASK_MIN_MAX; }
174 :
175 : /**
176 : * Check whether this attribute is nullable.
177 : */
178 569 : bool IsNullable() const { return mask & ATTRIBUTE_MASK_NULLABLE; }
179 :
180 : /**
181 : * Check whether this attribute is readonly.
182 : */
183 9807 : bool IsReadOnly() const { return !(mask & ATTRIBUTE_MASK_WRITABLE); }
184 :
185 : /**
186 : * Check whether this attribute requires a timed write.
187 : */
188 9804 : bool MustUseTimedWrite() const { return mask & ATTRIBUTE_MASK_MUST_USE_TIMED_WRITE; }
189 :
190 : /**
191 : * Check whether this attibute's storage is managed outside the built-in
192 : * attribute store.
193 : */
194 0 : bool IsExternal() const { return mask & ATTRIBUTE_MASK_EXTERNAL_STORAGE; }
195 :
196 : /**
197 : * Check whether this is a "singleton" attribute, in the sense that it has a
198 : * single value across multiple instances of the cluster. This is not
199 : * mutually exclusive with the attribute being external.
200 : */
201 0 : bool IsSingleton() const { return mask & ATTRIBUTE_MASK_SINGLETON; }
202 :
203 : /**
204 : * Check whether this attribute is automatically stored in non-volatile
205 : * memory.
206 : */
207 0 : bool IsAutomaticallyPersisted() const { return (mask & ATTRIBUTE_MASK_NONVOLATILE) && !IsExternal(); }
208 : };
209 :
210 : /** @brief Returns true if the given attribute type is a string. */
211 : bool emberAfIsStringAttributeType(EmberAfAttributeType attributeType);
212 :
213 : /** @brief Returns true if the given attribute type is a long string. */
214 : bool emberAfIsLongStringAttributeType(EmberAfAttributeType attributeType);
|