Line data Source code
1 : /*
2 : *
3 : * Copyright (c) 2020 Project CHIP Authors
4 : * Copyright (c) 2013-2017 Nest Labs, Inc.
5 : *
6 : * Licensed under the Apache License, Version 2.0 (the "License");
7 : * you may not use this file except in compliance with the License.
8 : * You may obtain a copy of the License at
9 : *
10 : * http://www.apache.org/licenses/LICENSE-2.0
11 : *
12 : * Unless required by applicable law or agreed to in writing, software
13 : * distributed under the License is distributed on an "AS IS" BASIS,
14 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 : * See the License for the specific language governing permissions and
16 : * limitations under the License.
17 : */
18 :
19 : /**
20 : * @file
21 : * This file contains definitions for working with CHIP TLV types.
22 : *
23 : */
24 :
25 : #pragma once
26 :
27 : #include <cstdint>
28 :
29 : namespace chip {
30 : namespace TLV {
31 :
32 : /**
33 : * An enumeration identifying the type of a TLV element.
34 : */
35 : enum TLVType
36 : {
37 : kTLVType_NotSpecified = -1,
38 : kTLVType_UnknownContainer = -2,
39 :
40 : kTLVType_SignedInteger = 0x00,
41 : kTLVType_UnsignedInteger = 0x04,
42 : kTLVType_Boolean = 0x08,
43 : kTLVType_FloatingPointNumber = 0x0A,
44 : kTLVType_UTF8String = 0x0C,
45 : kTLVType_ByteString = 0x10,
46 : // IMPORTANT: Values starting at Null must match the corresponding values of
47 : // TLVElementType.
48 : kTLVType_Null = 0x14,
49 : kTLVType_Structure = 0x15,
50 : kTLVType_Array = 0x16,
51 : kTLVType_List = 0x17
52 : };
53 :
54 : // TODO: Move to private namespace
55 : enum class TLVElementType : int8_t
56 : {
57 : // IMPORTANT: All values here except NotSpecified must have no bits in
58 : // common with values of TagControl.
59 : NotSpecified = -1,
60 : Int8 = 0x00,
61 : Int16 = 0x01,
62 : Int32 = 0x02,
63 : Int64 = 0x03,
64 : UInt8 = 0x04,
65 : UInt16 = 0x05,
66 : UInt32 = 0x06,
67 : UInt64 = 0x07,
68 : BooleanFalse = 0x08,
69 : BooleanTrue = 0x09,
70 : FloatingPointNumber32 = 0x0A,
71 : FloatingPointNumber64 = 0x0B,
72 : UTF8String_1ByteLength = 0x0C,
73 : UTF8String_2ByteLength = 0x0D,
74 : UTF8String_4ByteLength = 0x0E,
75 : UTF8String_8ByteLength = 0x0F,
76 : ByteString_1ByteLength = 0x10,
77 : ByteString_2ByteLength = 0x11,
78 : ByteString_4ByteLength = 0x12,
79 : ByteString_8ByteLength = 0x13,
80 : // IMPORTANT: Values starting at Null must match the corresponding values of
81 : // TLVType.
82 : Null = 0x14,
83 : Structure = 0x15,
84 : Array = 0x16,
85 : List = 0x17,
86 : EndOfContainer = 0x18
87 : };
88 :
89 : template <typename T>
90 : inline bool operator<=(const T & lhs, TLVElementType rhs)
91 : {
92 : return lhs <= static_cast<int8_t>(rhs);
93 : }
94 :
95 : template <typename T>
96 : inline bool operator>=(const T & lhs, TLVElementType rhs)
97 : {
98 : return lhs >= static_cast<int8_t>(rhs);
99 : }
100 :
101 : // TODO: Move to private namespace
102 : enum TLVFieldSize
103 : {
104 : kTLVFieldSize_0Byte = -1,
105 : kTLVFieldSize_1Byte = 0,
106 : kTLVFieldSize_2Byte = 1,
107 : kTLVFieldSize_4Byte = 2,
108 : kTLVFieldSize_8Byte = 3
109 : };
110 :
111 : // TODO: Move to private namespace
112 : enum
113 : {
114 : kTLVTypeMask = 0x1F,
115 : kTLVTypeSizeMask = 0x03
116 : };
117 :
118 : /**
119 : * Returns true if the specified TLV type is valid.
120 : *
121 : * @return @p true if the specified TLV type is valid; otherwise @p false.
122 : */
123 10487832 : inline bool IsValidTLVType(TLVElementType type)
124 : {
125 10487832 : return type <= TLVElementType::EndOfContainer;
126 : }
127 :
128 : /**
129 : * Returns true if the specified TLV type implies the presence of an associated value field.
130 : *
131 : * @return @p true if the specified TLV type implies the presence of an associated value field; otherwise @p false.
132 : */
133 10800706 : inline bool TLVTypeHasValue(TLVElementType type)
134 : {
135 15739198 : return (type <= TLVElementType::UInt64 ||
136 15739198 : (type >= TLVElementType::FloatingPointNumber32 && type <= TLVElementType::ByteString_8ByteLength));
137 : }
138 :
139 : /**
140 : * Returns true if the specified TLV type implies the presence of an associated length field.
141 : *
142 : * @return @p true if the specified TLV type implies the presence of an associated length field; otherwise @p false.
143 : */
144 21014266 : inline bool TLVTypeHasLength(TLVElementType type)
145 : {
146 21014266 : return type >= TLVElementType::UTF8String_1ByteLength && type <= TLVElementType::ByteString_8ByteLength;
147 : }
148 :
149 : /**
150 : * Returns true if the specified TLV type is a container.
151 : *
152 : * @return @p true if the specified TLV type is a container; otherwise @p false.
153 : */
154 13145579 : inline bool TLVTypeIsContainer(TLVElementType type)
155 : {
156 13145579 : return type >= TLVElementType::Structure && type <= TLVElementType::List;
157 : }
158 :
159 158548 : inline bool TLVTypeIsContainer(TLVType type)
160 : {
161 158548 : return type >= kTLVType_Structure && type <= kTLVType_List;
162 : }
163 :
164 : /**
165 : * Returns true if the specified TLV type is a UTF8 or byte string.
166 : *
167 : * @return @p true if the specified TLV type is a UTF8 or byte string; otherwise @p false.
168 : */
169 7752887 : inline bool TLVTypeIsString(TLVElementType type)
170 : {
171 7752887 : return type >= TLVElementType::UTF8String_1ByteLength && type <= TLVElementType::ByteString_8ByteLength;
172 : }
173 :
174 : /**
175 : * Returns true if the specified TLV type is a UTF8 string.
176 : *
177 : * @return @p true if the specified TLV type is a UTF8 string; otherwise @p false.
178 : */
179 444 : inline bool TLVTypeIsUTF8String(TLVElementType type)
180 : {
181 444 : return type >= TLVElementType::UTF8String_1ByteLength && type <= TLVElementType::UTF8String_8ByteLength;
182 : }
183 :
184 : /**
185 : * Returns true if the specified TLV type is a byte string.
186 : *
187 : * @return @p true if the specified TLV type is a byte string; otherwise @p false.
188 : */
189 301 : inline bool TLVTypeIsByteString(TLVElementType type)
190 : {
191 301 : return type >= TLVElementType::ByteString_1ByteLength && type <= TLVElementType::ByteString_8ByteLength;
192 : }
193 :
194 : // TODO: move to private namespace
195 10800706 : inline TLVFieldSize GetTLVFieldSize(TLVElementType type)
196 : {
197 10800706 : if (TLVTypeHasValue(type))
198 3250872 : return static_cast<TLVFieldSize>(static_cast<uint8_t>(type) & kTLVTypeSizeMask);
199 7549834 : return kTLVFieldSize_0Byte;
200 : }
201 :
202 : // TODO: move to private namespace
203 10483731 : inline uint8_t TLVFieldSizeToBytes(TLVFieldSize fieldSize)
204 : {
205 : // We would like to assert fieldSize < 7, but that gives us fatal
206 : // -Wtautological-constant-out-of-range-compare warnings...
207 10483731 : return static_cast<uint8_t>((fieldSize != kTLVFieldSize_0Byte) ? (1 << fieldSize) : 0);
208 : }
209 :
210 : } // namespace TLV
211 : } // namespace chip
|