3 * Copyright (c) 2020-2021 Project CHIP Authors
4 * Copyright (c) 2013-2017 Nest Labs, Inc.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
22 * This file implements unit tests for the CHIP TLV implementation.
26 #include <nlbyteorder.h>
27 #include <nlunit-test.h>
29 #include <core/CHIPCircularTLVBuffer.h>
30 #include <core/CHIPCore.h>
31 #include <core/CHIPTLV.h>
32 #include <core/CHIPTLVData.hpp>
33 #include <core/CHIPTLVDebug.hpp>
34 #include <core/CHIPTLVUtilities.hpp>
36 #include <support/CHIPMem.h>
37 #include <support/CodeUtils.h>
38 #include <support/RandUtils.h>
39 #include <support/ScopedBuffer.h>
40 #include <support/UnitTestRegistration.h>
42 #include <system/TLVPacketBufferBackingStore.h>
47 using namespace chip::TLV;
51 TestProfile_1 = 0xAABBCCDD,
52 TestProfile_2 = 0x11223344
56 static const char sLargeString [] =
58 "!123456789ABCDEF@123456789ABCDEF#123456789ABCDEF$123456789ABCDEF%123456789ABCDEF^123456789ABCDEF&123456789ABCDEF*123456789ABCDEF"
59 "01234567(9ABCDEF01234567)9ABCDEF01234567-9ABCDEF01234567=9ABCDEF01234567[9ABCDEF01234567]9ABCDEF01234567;9ABCDEF01234567'9ABCDEF"
63 void TestAndOpenContainer(nlTestSuite * inSuite, TLVReader & reader, TLVType type, uint64_t tag, TLVReader & containerReader)
65 NL_TEST_ASSERT(inSuite, reader.GetType() == type);
66 NL_TEST_ASSERT(inSuite, reader.GetTag() == tag);
67 NL_TEST_ASSERT(inSuite, reader.GetLength() == 0);
69 CHIP_ERROR err = reader.OpenContainer(containerReader);
70 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
72 NL_TEST_ASSERT(inSuite, containerReader.GetContainerType() == type);
76 void TestAndEnterContainer(nlTestSuite * inSuite, T & t, TLVType type, uint64_t tag, TLVType & outerContainerType)
78 NL_TEST_ASSERT(inSuite, t.GetType() == type);
79 NL_TEST_ASSERT(inSuite, t.GetTag() == tag);
80 NL_TEST_ASSERT(inSuite, t.GetLength() == 0);
82 TLVType expectedContainerType = t.GetContainerType();
84 CHIP_ERROR err = t.EnterContainer(outerContainerType);
85 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
87 NL_TEST_ASSERT(inSuite, outerContainerType == expectedContainerType);
88 NL_TEST_ASSERT(inSuite, t.GetContainerType() == type);
92 void TestNext(nlTestSuite * inSuite, T & t)
94 CHIP_ERROR err = t.Next();
95 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
98 void TestSkip(nlTestSuite * inSuite, TLVReader & reader)
100 CHIP_ERROR err = reader.Skip();
101 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
104 void TestMove(nlTestSuite * inSuite, TLVUpdater & updater)
106 CHIP_ERROR err = updater.Move();
107 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
111 void TestEnd(nlTestSuite * inSuite, T & t)
116 NL_TEST_ASSERT(inSuite, err == CHIP_END_OF_TLV);
119 void TestEndAndCloseContainer(nlTestSuite * inSuite, TLVReader & reader, TLVReader & containerReader)
123 TestEnd<TLVReader>(inSuite, containerReader);
125 err = reader.CloseContainer(containerReader);
126 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
130 void TestEndAndExitContainer(nlTestSuite * inSuite, T & t, TLVType outerContainerType)
134 TestEnd<T>(inSuite, t);
136 err = t.ExitContainer(outerContainerType);
137 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
139 NL_TEST_ASSERT(inSuite, t.GetContainerType() == outerContainerType);
142 template <class S, class T>
143 void TestGet(nlTestSuite * inSuite, S & s, TLVType type, uint64_t tag, T expectedVal)
145 NL_TEST_ASSERT(inSuite, s.GetType() == type);
146 NL_TEST_ASSERT(inSuite, s.GetTag() == tag);
147 NL_TEST_ASSERT(inSuite, s.GetLength() == 0);
150 CHIP_ERROR err = s.Get(val);
151 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
153 NL_TEST_ASSERT(inSuite, val == expectedVal);
156 void ForEachElement(nlTestSuite * inSuite, TLVReader & reader, void * context,
157 void (*cb)(nlTestSuite * inSuite, TLVReader & reader, void * context))
164 if (err == CHIP_END_OF_TLV)
168 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
172 cb(inSuite, reader, context);
175 if (TLVTypeIsContainer(reader.GetType()))
177 TLVType outerContainerType;
179 err = reader.EnterContainer(outerContainerType);
180 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
182 ForEachElement(inSuite, reader, context, cb);
184 err = reader.ExitContainer(outerContainerType);
185 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
194 struct TestTLVContext
196 nlTestSuite * mSuite;
198 uint32_t mEvictedBytes;
201 void TestNull(nlTestSuite * inSuite, TLVReader & reader, uint64_t tag)
203 NL_TEST_ASSERT(inSuite, reader.GetType() == kTLVType_Null);
204 NL_TEST_ASSERT(inSuite, reader.GetTag() == tag);
205 NL_TEST_ASSERT(inSuite, reader.GetLength() == 0);
208 void TestString(nlTestSuite * inSuite, TLVReader & reader, uint64_t tag, const char * expectedVal)
210 NL_TEST_ASSERT(inSuite, reader.GetType() == kTLVType_UTF8String);
211 NL_TEST_ASSERT(inSuite, reader.GetTag() == tag);
213 size_t expectedLen = strlen(expectedVal);
214 NL_TEST_ASSERT(inSuite, reader.GetLength() == expectedLen);
216 chip::Platform::ScopedMemoryBuffer<char> valBuffer;
217 char * val = static_cast<char *>(valBuffer.Alloc(expectedLen + 1).Get());
219 CHIP_ERROR err = reader.GetString(val, static_cast<uint32_t>(expectedLen) + 1);
220 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
222 NL_TEST_ASSERT(inSuite, memcmp(val, expectedVal, expectedLen + 1) == 0);
225 void TestDupString(nlTestSuite * inSuite, TLVReader & reader, uint64_t tag, const char * expectedVal)
227 NL_TEST_ASSERT(inSuite, reader.GetType() == kTLVType_UTF8String);
228 NL_TEST_ASSERT(inSuite, reader.GetTag() == tag);
230 size_t expectedLen = strlen(expectedVal);
231 NL_TEST_ASSERT(inSuite, reader.GetLength() == expectedLen);
233 chip::Platform::ScopedMemoryBuffer<char> valBuffer;
234 char * val = valBuffer.Alloc(expectedLen + 1).Get();
236 CHIP_ERROR err = reader.DupString(val);
237 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
239 NL_TEST_ASSERT(inSuite, memcmp(val, expectedVal, expectedLen + 1) == 0);
242 void TestDupBytes(nlTestSuite * inSuite, TLVReader & reader, uint64_t tag, const uint8_t * expectedVal, uint32_t expectedLen)
244 NL_TEST_ASSERT(inSuite, reader.GetType() == kTLVType_UTF8String);
245 NL_TEST_ASSERT(inSuite, reader.GetTag() == tag);
247 NL_TEST_ASSERT(inSuite, reader.GetLength() == expectedLen);
249 chip::Platform::ScopedMemoryBuffer<uint8_t> valBuffer;
250 uint8_t * val = valBuffer.Alloc(expectedLen).Get();
251 CHIP_ERROR err = reader.DupBytes(val, expectedLen);
252 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
254 NL_TEST_ASSERT(inSuite, memcmp(val, expectedVal, expectedLen) == 0);
257 void TestBufferContents(nlTestSuite * inSuite, const System::PacketBufferHandle & buffer, const uint8_t * expectedVal,
258 uint32_t expectedLen)
260 System::PacketBufferHandle buf = buffer.Retain();
261 while (!buf.IsNull())
263 uint16_t len = buf->DataLength();
264 NL_TEST_ASSERT(inSuite, len <= expectedLen);
266 NL_TEST_ASSERT(inSuite, memcmp(buf->Start(), expectedVal, len) == 0);
274 NL_TEST_ASSERT(inSuite, expectedLen == 0);
278 static const uint8_t Encoding1[] =
280 0xD5, 0xBB, 0xAA, 0xDD, 0xCC, 0x01, 0x00, 0xC9, 0xBB, 0xAA, 0xDD, 0xCC, 0x02, 0x00, 0x88, 0x02,
281 0x00, 0x36, 0x00, 0x00, 0x2A, 0x00, 0xEF, 0x02, 0xF0, 0x67, 0xFD, 0xFF, 0x07, 0x00, 0x90, 0x2F,
282 0x50, 0x09, 0x00, 0x00, 0x00, 0x15, 0x18, 0x17, 0xD4, 0xBB, 0xAA, 0xDD, 0xCC, 0x11, 0x00, 0xB4,
283 0xA0, 0xBB, 0x0D, 0x00, 0x14, 0xB5, 0x00, 0x28, 0x6B, 0xEE, 0x6D, 0x70, 0x11, 0x01, 0x00, 0x0E,
284 0x01, 0x53, 0x54, 0x41, 0x52, 0x54, 0x2E, 0x2E, 0x2E, 0x21, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
285 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x40, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
286 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x23, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
287 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x24, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
288 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x25, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
289 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x5E, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
290 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x26, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
291 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x2A, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
292 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
293 0x37, 0x28, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
294 0x37, 0x29, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
295 0x37, 0x2D, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
296 0x37, 0x3D, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
297 0x37, 0x5B, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
298 0x37, 0x5D, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
299 0x37, 0x3B, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
300 0x37, 0x27, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x2E, 0x2E, 0x2E, 0x45, 0x4E, 0x44, 0x18,
301 0x18, 0x18, 0xCC, 0xBB, 0xAA, 0xDD, 0xCC, 0x05, 0x00, 0x0E, 0x54, 0x68, 0x69, 0x73, 0x20, 0x69,
302 0x73, 0x20, 0x61, 0x20, 0x74, 0x65, 0x73, 0x74, 0x8A, 0xFF, 0xFF, 0x33, 0x33, 0x8F, 0x41, 0xAB,
303 0x00, 0x00, 0x01, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0xE6, 0x31, 0x40, 0x18
308 static const uint8_t Encoding1_DataMacro [] =
310 CHIP_TLV_STRUCTURE(CHIP_TLV_TAG_FULLY_QUALIFIED_6Bytes(TestProfile_1, 1)),
311 CHIP_TLV_BOOL(CHIP_TLV_TAG_FULLY_QUALIFIED_6Bytes(TestProfile_1, 2), true),
312 CHIP_TLV_BOOL(CHIP_TLV_TAG_IMPLICIT_PROFILE_2Bytes(2), false),
313 CHIP_TLV_ARRAY(CHIP_TLV_TAG_CONTEXT_SPECIFIC(0)),
314 CHIP_TLV_INT8(CHIP_TLV_TAG_ANONYMOUS, 42),
315 CHIP_TLV_INT8(CHIP_TLV_TAG_ANONYMOUS, -17),
316 CHIP_TLV_INT32(CHIP_TLV_TAG_ANONYMOUS, -170000),
317 CHIP_TLV_UINT64(CHIP_TLV_TAG_ANONYMOUS, 40000000000ULL),
318 CHIP_TLV_STRUCTURE(CHIP_TLV_TAG_ANONYMOUS),
319 CHIP_TLV_END_OF_CONTAINER,
320 CHIP_TLV_PATH(CHIP_TLV_TAG_ANONYMOUS),
321 CHIP_TLV_NULL(CHIP_TLV_TAG_FULLY_QUALIFIED_6Bytes(TestProfile_1, 17)),
322 CHIP_TLV_NULL(CHIP_TLV_TAG_IMPLICIT_PROFILE_4Bytes(900000)),
323 CHIP_TLV_NULL(CHIP_TLV_TAG_ANONYMOUS),
324 CHIP_TLV_STRUCTURE(CHIP_TLV_TAG_IMPLICIT_PROFILE_4Bytes(4000000000ULL)),
325 CHIP_TLV_UTF8_STRING_2ByteLength(CHIP_TLV_TAG_COMMON_PROFILE_4Bytes(70000), sizeof(sLargeString) - 1,
326 'S', 'T', 'A', 'R', 'T', '.', '.', '.',
327 '!', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', '@',
328 '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', '#', '1',
329 '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', '$', '1', '2',
330 '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', '%', '1', '2', '3',
331 '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', '^', '1', '2', '3', '4',
332 '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', '&', '1', '2', '3', '4', '5',
333 '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', '*', '1', '2', '3', '4', '5', '6',
334 '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
335 '0', '1', '2', '3', '4', '5', '6', '7', '(', '9', 'A', 'B', 'C', 'D', 'E', 'F', '0',
336 '1', '2', '3', '4', '5', '6', '7', ')', '9', 'A', 'B', 'C', 'D', 'E', 'F', '0', '1',
337 '2', '3', '4', '5', '6', '7', '-', '9', 'A', 'B', 'C', 'D', 'E', 'F', '0', '1', '2',
338 '3', '4', '5', '6', '7', '=', '9', 'A', 'B', 'C', 'D', 'E', 'F', '0', '1', '2', '3',
339 '4', '5', '6', '7', '[', '9', 'A', 'B', 'C', 'D', 'E', 'F', '0', '1', '2', '3', '4',
340 '5', '6', '7', ']', '9', 'A', 'B', 'C', 'D', 'E', 'F', '0', '1', '2', '3', '4', '5',
341 '6', '7', ';', '9', 'A', 'B', 'C', 'D', 'E', 'F', '0', '1', '2', '3', '4', '5', '6',
342 '7', '\'', '9', 'A', 'B', 'C', 'D', 'E', 'F',
343 '.', '.', '.', 'E', 'N', 'D'),
344 CHIP_TLV_END_OF_CONTAINER,
345 CHIP_TLV_END_OF_CONTAINER,
346 CHIP_TLV_END_OF_CONTAINER,
347 CHIP_TLV_UTF8_STRING_1ByteLength(CHIP_TLV_TAG_FULLY_QUALIFIED_6Bytes(TestProfile_1, 5), sizeof("This is a test") - 1,
348 'T', 'h', 'i', 's', ' ', 'i', 's', ' ', 'a', ' ', 't', 'e', 's', 't'),
349 CHIP_TLV_FLOAT32(CHIP_TLV_TAG_IMPLICIT_PROFILE_2Bytes(65535),
350 0x33, 0x33, 0x8f, 0x41), // (float)17.9
351 CHIP_TLV_FLOAT64(CHIP_TLV_TAG_IMPLICIT_PROFILE_4Bytes(65536),
352 0x66, 0x66, 0x66, 0x66, 0x66, 0xE6, 0x31, 0x40), // (double)17.9
353 CHIP_TLV_END_OF_CONTAINER
357 void WriteEncoding1(nlTestSuite * inSuite, TLVWriter & writer)
362 err = writer.OpenContainer(ProfileTag(TestProfile_1, 1), kTLVType_Structure, writer2);
363 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
365 err = writer2.PutBoolean(ProfileTag(TestProfile_1, 2), true);
366 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
368 err = writer2.PutBoolean(ProfileTag(TestProfile_2, 2), false);
369 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
374 err = writer2.OpenContainer(ContextTag(0), kTLVType_Array, writer3);
375 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
377 // TODO(#1306): expand coverage of inttype encoding tests.
378 err = writer3.Put(AnonymousTag, static_cast<int32_t>(42));
379 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
381 err = writer3.Put(AnonymousTag, static_cast<int32_t>(-17));
382 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
384 err = writer3.Put(AnonymousTag, static_cast<int32_t>(-170000));
385 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
387 err = writer3.Put(AnonymousTag, static_cast<uint64_t>(40000000000ULL));
388 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
393 err = writer3.OpenContainer(AnonymousTag, kTLVType_Structure, writer4);
394 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
396 err = writer3.CloseContainer(writer4);
397 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
403 err = writer3.OpenContainer(AnonymousTag, kTLVType_List, writer5);
404 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
406 err = writer5.PutNull(ProfileTag(TestProfile_1, 17));
407 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
409 err = writer5.PutNull(ProfileTag(TestProfile_2, 900000));
410 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
412 err = writer5.PutNull(AnonymousTag);
413 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
416 TLVType outerContainerType;
418 err = writer5.StartContainer(ProfileTag(TestProfile_2, 4000000000ULL), kTLVType_Structure, outerContainerType);
419 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
421 err = writer5.PutString(CommonTag(70000), sLargeString);
422 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
424 err = writer5.EndContainer(outerContainerType);
425 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
428 err = writer3.CloseContainer(writer5);
429 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
432 err = writer2.CloseContainer(writer3);
433 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
436 err = writer2.PutString(ProfileTag(TestProfile_1, 5), "This is a test");
437 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
439 err = writer2.Put(ProfileTag(TestProfile_2, 65535), static_cast<float>(17.9));
440 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
442 err = writer2.Put(ProfileTag(TestProfile_2, 65536), 17.9);
443 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
445 err = writer.CloseContainer(writer2);
446 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
448 err = writer.Finalize();
449 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
452 void WriteEmptyEncoding(nlTestSuite * inSuite, TLVWriter & writer)
457 err = writer.OpenContainer(ProfileTag(TestProfile_1, 1), kTLVType_Structure, writer2);
458 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
463 err = writer2.OpenContainer(ProfileTag(TestProfile_1, 256), kTLVType_Array, writer3);
464 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
466 err = writer2.CloseContainer(writer3);
467 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
470 err = writer.CloseContainer(writer2);
471 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
473 err = writer.Finalize();
474 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
477 void ReadEncoding1(nlTestSuite * inSuite, TLVReader & reader)
479 TestNext<TLVReader>(inSuite, reader);
484 TestAndOpenContainer(inSuite, reader, kTLVType_Structure, ProfileTag(TestProfile_1, 1), reader2);
486 TestNext<TLVReader>(inSuite, reader2);
488 TestGet<TLVReader, bool>(inSuite, reader2, kTLVType_Boolean, ProfileTag(TestProfile_1, 2), true);
490 TestNext<TLVReader>(inSuite, reader2);
492 TestGet<TLVReader, bool>(inSuite, reader2, kTLVType_Boolean, ProfileTag(TestProfile_2, 2), false);
494 TestNext<TLVReader>(inSuite, reader2);
499 TestAndOpenContainer(inSuite, reader2, kTLVType_Array, ContextTag(0), reader3);
501 TestNext<TLVReader>(inSuite, reader3);
503 TestGet<TLVReader, int8_t>(inSuite, reader3, kTLVType_SignedInteger, AnonymousTag, 42);
504 TestGet<TLVReader, int16_t>(inSuite, reader3, kTLVType_SignedInteger, AnonymousTag, 42);
505 TestGet<TLVReader, int32_t>(inSuite, reader3, kTLVType_SignedInteger, AnonymousTag, 42);
506 TestGet<TLVReader, int64_t>(inSuite, reader3, kTLVType_SignedInteger, AnonymousTag, 42);
507 TestGet<TLVReader, uint8_t>(inSuite, reader3, kTLVType_SignedInteger, AnonymousTag, 42);
508 TestGet<TLVReader, uint16_t>(inSuite, reader3, kTLVType_SignedInteger, AnonymousTag, 42);
509 TestGet<TLVReader, uint32_t>(inSuite, reader3, kTLVType_SignedInteger, AnonymousTag, 42);
510 TestGet<TLVReader, uint64_t>(inSuite, reader3, kTLVType_SignedInteger, AnonymousTag, 42);
512 TestNext<TLVReader>(inSuite, reader3);
514 TestGet<TLVReader, int8_t>(inSuite, reader3, kTLVType_SignedInteger, AnonymousTag, -17);
515 TestGet<TLVReader, int16_t>(inSuite, reader3, kTLVType_SignedInteger, AnonymousTag, -17);
516 TestGet<TLVReader, int32_t>(inSuite, reader3, kTLVType_SignedInteger, AnonymousTag, -17);
517 TestGet<TLVReader, int64_t>(inSuite, reader3, kTLVType_SignedInteger, AnonymousTag, -17);
519 TestNext<TLVReader>(inSuite, reader3);
521 TestGet<TLVReader, int32_t>(inSuite, reader3, kTLVType_SignedInteger, AnonymousTag, -170000);
522 TestGet<TLVReader, int64_t>(inSuite, reader3, kTLVType_SignedInteger, AnonymousTag, -170000);
524 TestNext<TLVReader>(inSuite, reader3);
526 TestGet<TLVReader, int64_t>(inSuite, reader3, kTLVType_UnsignedInteger, AnonymousTag, 40000000000ULL);
527 TestGet<TLVReader, uint64_t>(inSuite, reader3, kTLVType_UnsignedInteger, AnonymousTag, 40000000000ULL);
529 TestNext<TLVReader>(inSuite, reader3);
534 TestAndOpenContainer(inSuite, reader3, kTLVType_Structure, AnonymousTag, reader4);
536 TestEndAndCloseContainer(inSuite, reader3, reader4);
539 TestNext<TLVReader>(inSuite, reader3);
544 TestAndOpenContainer(inSuite, reader3, kTLVType_List, AnonymousTag, reader5);
546 TestNext<TLVReader>(inSuite, reader5);
548 TestNull(inSuite, reader5, ProfileTag(TestProfile_1, 17));
550 TestNext<TLVReader>(inSuite, reader5);
552 TestNull(inSuite, reader5, ProfileTag(TestProfile_2, 900000));
554 TestNext<TLVReader>(inSuite, reader5);
556 TestNull(inSuite, reader5, AnonymousTag);
558 TestNext<TLVReader>(inSuite, reader5);
561 TLVType outerContainerType;
563 TestAndEnterContainer<TLVReader>(inSuite, reader5, kTLVType_Structure, ProfileTag(TestProfile_2, 4000000000ULL),
566 TestNext<TLVReader>(inSuite, reader5);
568 TestString(inSuite, reader5, CommonTag(70000), sLargeString);
570 TestEndAndExitContainer<TLVReader>(inSuite, reader5, outerContainerType);
573 TestEndAndCloseContainer(inSuite, reader3, reader5);
576 TestEndAndCloseContainer(inSuite, reader2, reader3);
579 TestNext<TLVReader>(inSuite, reader2);
581 TestString(inSuite, reader2, ProfileTag(TestProfile_1, 5), "This is a test");
583 TestNext<TLVReader>(inSuite, reader2);
585 TestGet<TLVReader, double>(inSuite, reader2, kTLVType_FloatingPointNumber, ProfileTag(TestProfile_2, 65535),
586 static_cast<float>(17.9));
588 TestNext<TLVReader>(inSuite, reader2);
590 TestGet<TLVReader, double>(inSuite, reader2, kTLVType_FloatingPointNumber, ProfileTag(TestProfile_2, 65536), 17.9);
592 TestEndAndCloseContainer(inSuite, reader, reader2);
595 TestEnd<TLVReader>(inSuite, reader);
598 void WriteEncoding2(nlTestSuite * inSuite, TLVWriter & writer)
605 err = writer.OpenContainer(ProfileTag(TestProfile_1, 1), kTLVType_Structure, writer1);
606 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
608 err = writer1.PutBoolean(ProfileTag(TestProfile_1, 2), true);
609 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
611 err = writer1.PutBoolean(ProfileTag(TestProfile_2, 2), false);
612 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
614 err = writer.CloseContainer(writer1);
615 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
621 err = writer.OpenContainer(ProfileTag(TestProfile_2, 1), kTLVType_Structure, writer1);
622 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
624 err = writer1.PutBoolean(ProfileTag(TestProfile_2, 2), false);
625 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
627 err = writer1.PutBoolean(ProfileTag(TestProfile_1, 2), true);
628 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
630 err = writer.CloseContainer(writer1);
631 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
634 err = writer.Finalize();
635 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
638 void WriteEncoding3(nlTestSuite * inSuite, TLVWriter & writer)
645 err = writer.OpenContainer(ProfileTag(TestProfile_1, 1), kTLVType_Structure, writer1);
647 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
649 err = writer1.PutBoolean(ProfileTag(TestProfile_2, 2), false);
650 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
652 err = writer.CloseContainer(writer1);
653 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
656 err = writer.Finalize();
657 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
660 void ReadEncoding3(nlTestSuite * inSuite, TLVReader & reader)
664 TestAndOpenContainer(inSuite, reader, kTLVType_Structure, ProfileTag(TestProfile_1, 1), reader2);
666 TestNext<TLVReader>(inSuite, reader2);
668 TestGet<TLVReader, bool>(inSuite, reader2, kTLVType_Boolean, ProfileTag(TestProfile_2, 2), false);
670 TestEndAndCloseContainer(inSuite, reader, reader2);
673 static const uint8_t Encoding5_DataMacro [] =
675 CHIP_TLV_STRUCTURE(CHIP_TLV_TAG_FULLY_QUALIFIED_6Bytes(TestProfile_1, 1)),
676 CHIP_TLV_BOOL(CHIP_TLV_TAG_FULLY_QUALIFIED_6Bytes(TestProfile_1, 2), true),
677 CHIP_TLV_BOOL(CHIP_TLV_TAG_IMPLICIT_PROFILE_2Bytes(2), false),
678 CHIP_TLV_BOOL(CHIP_TLV_TAG_FULLY_QUALIFIED_6Bytes(TestProfile_1, 2), false),
679 CHIP_TLV_BOOL(CHIP_TLV_TAG_IMPLICIT_PROFILE_2Bytes(2), true),
681 CHIP_TLV_STRUCTURE(CHIP_TLV_TAG_FULLY_QUALIFIED_6Bytes(TestProfile_1, 1)),
682 CHIP_TLV_BOOL(CHIP_TLV_TAG_FULLY_QUALIFIED_6Bytes(TestProfile_1, 2), true),
683 CHIP_TLV_BOOL(CHIP_TLV_TAG_IMPLICIT_PROFILE_2Bytes(2), false),
684 CHIP_TLV_END_OF_CONTAINER,
686 CHIP_TLV_STRUCTURE(CHIP_TLV_TAG_IMPLICIT_PROFILE_2Bytes(1)),
687 CHIP_TLV_BOOL(CHIP_TLV_TAG_IMPLICIT_PROFILE_2Bytes(2), false),
688 CHIP_TLV_BOOL(CHIP_TLV_TAG_FULLY_QUALIFIED_6Bytes(TestProfile_1, 2), true),
689 CHIP_TLV_END_OF_CONTAINER,
690 CHIP_TLV_END_OF_CONTAINER,
692 CHIP_TLV_STRUCTURE(CHIP_TLV_TAG_IMPLICIT_PROFILE_2Bytes(1)),
693 CHIP_TLV_BOOL(CHIP_TLV_TAG_IMPLICIT_PROFILE_2Bytes(2), false),
694 CHIP_TLV_BOOL(CHIP_TLV_TAG_FULLY_QUALIFIED_6Bytes(TestProfile_1, 2), true),
695 CHIP_TLV_END_OF_CONTAINER,
699 void WriteEncoding5(nlTestSuite * inSuite, TLVWriter & writer)
706 err = writer.OpenContainer(ProfileTag(TestProfile_1, 1), kTLVType_Structure, writer1);
707 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
709 err = writer1.PutBoolean(ProfileTag(TestProfile_1, 2), true);
710 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
712 err = writer1.PutBoolean(ProfileTag(TestProfile_2, 2), false);
713 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
715 err = writer1.PutBoolean(ProfileTag(TestProfile_1, 2), false);
716 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
718 err = writer1.PutBoolean(ProfileTag(TestProfile_2, 2), true);
719 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
721 { // Inner Container 1
724 err = writer1.OpenContainer(ProfileTag(TestProfile_1, 1), kTLVType_Structure, writer2);
725 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
727 err = writer2.PutBoolean(ProfileTag(TestProfile_1, 2), true);
728 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
730 err = writer2.PutBoolean(ProfileTag(TestProfile_2, 2), false);
731 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
733 err = writer1.CloseContainer(writer2);
734 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
737 { // Inner Container 2
740 err = writer1.OpenContainer(ProfileTag(TestProfile_2, 1), kTLVType_Structure, writer2);
741 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
743 err = writer2.PutBoolean(ProfileTag(TestProfile_2, 2), false);
744 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
746 err = writer2.PutBoolean(ProfileTag(TestProfile_1, 2), true);
747 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
749 err = writer1.CloseContainer(writer2);
750 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
753 err = writer.CloseContainer(writer1);
754 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
760 err = writer.OpenContainer(ProfileTag(TestProfile_2, 1), kTLVType_Structure, writer1);
761 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
763 err = writer1.PutBoolean(ProfileTag(TestProfile_2, 2), false);
764 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
766 err = writer1.PutBoolean(ProfileTag(TestProfile_1, 2), true);
767 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
769 err = writer.CloseContainer(writer1);
770 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
773 err = writer.Finalize();
774 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
780 * This function appends two boolean types and two container types to the first
783 * The boolean types are-
784 * <TestProfile_1, 2, false>
785 * <TestProfile_2, 2, true>
787 * The two new container types are-
788 * <TestProfile_1, 1, kTLVType_Structure, <TestProfile_1, 2, true> <TestProfile_2, 2, false> >,
789 * <TestProfile_2, 1, kTLVType_Structure, <TestProfile_2, 2, false> <TestProfile_1, 2, true> >
791 void AppendEncoding2(nlTestSuite * inSuite, uint8_t * buf, uint32_t dataLen, uint32_t maxLen, uint32_t & updatedLen)
797 err = updater.Init(buf, dataLen, maxLen);
798 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
800 updater.SetImplicitProfileId(TestProfile_2);
802 TestNext<TLVUpdater>(inSuite, updater);
805 TLVType outerContainerType;
807 TestAndEnterContainer<TLVUpdater>(inSuite, updater, kTLVType_Structure, ProfileTag(TestProfile_1, 1), outerContainerType);
809 TestNext<TLVUpdater>(inSuite, updater);
811 // Move the element without modification
812 TestMove(inSuite, updater);
814 TestNext<TLVUpdater>(inSuite, updater);
816 // Read and copy the element with/without modification
817 TestGet<TLVUpdater, bool>(inSuite, updater, kTLVType_Boolean, ProfileTag(TestProfile_2, 2), false);
818 err = updater.PutBoolean(ProfileTag(TestProfile_2, 2), false);
819 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
821 // TestEnd and add data at the end of the container
822 TestEnd<TLVUpdater>(inSuite, updater);
824 // Put new values in the encoding using the updater
825 // Add <TestProfile_1, 2, false>
826 err = updater.PutBoolean(ProfileTag(TestProfile_1, 2), false);
827 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
829 // Add <TestProfile_2, 2, true>
830 err = updater.PutBoolean(ProfileTag(TestProfile_2, 2), true);
831 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
833 // Add a new container
835 TLVType outerContainerType1;
837 err = updater.StartContainer(ProfileTag(TestProfile_1, 1), kTLVType_Structure, outerContainerType1);
838 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
840 // Add <TestProfile_1, 2, true>
841 err = updater.PutBoolean(ProfileTag(TestProfile_1, 2), true);
842 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
844 // Add <TestProfile_1, 2, true>
845 err = updater.PutBoolean(ProfileTag(TestProfile_2, 2), false);
846 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
848 // Close the container
849 err = updater.EndContainer(outerContainerType1);
850 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
853 // Add another new container
855 TLVType outerContainerType1;
857 err = updater.StartContainer(ProfileTag(TestProfile_2, 1), kTLVType_Structure, outerContainerType1);
858 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
860 // Add <TestProfile_2, 2, false>
861 err = updater.PutBoolean(ProfileTag(TestProfile_2, 2), false);
862 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
864 // Add <TestProfile_1, 2, true>
865 err = updater.PutBoolean(ProfileTag(TestProfile_1, 2), true);
866 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
868 // Close the container
869 err = updater.EndContainer(outerContainerType1);
870 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
873 TestEndAndExitContainer<TLVUpdater>(inSuite, updater, outerContainerType);
876 TestNext<TLVUpdater>(inSuite, updater);
878 // Move the container unmodified
879 TestMove(inSuite, updater);
881 TestEnd<TLVUpdater>(inSuite, updater);
883 err = updater.Finalize();
884 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
886 updatedLen = updater.GetLengthWritten();
890 * FindAppendEncoding2()
892 * This function appends two boolean types and two container types to the first
893 * container. It is very similar to AppendEncoding2() above except for the fact
894 * that it uses TLVUtilities::Find() to find the element of interest before
895 * appending new data.
897 * The boolean types are-
898 * <TestProfile_1, 2, false>
899 * <TestProfile_2, 2, true>
901 * The two new container types are-
902 * <TestProfile_1, 1, kTLVType_Structure, <TestProfile_1, 2, true> <TestProfile_2, 2, false> >,
903 * <TestProfile_2, 1, kTLVType_Structure, <TestProfile_2, 2, false> <TestProfile_1, 2, true> >
905 void FindAppendEncoding2(nlTestSuite * inSuite, uint8_t * buf, uint32_t dataLen, uint32_t maxLen, uint32_t & updatedLen,
913 // Initialize a reader
914 reader.Init(buf, dataLen);
915 reader.ImplicitProfileId = TestProfile_2;
919 // Find the container
921 TLVType outerContainerType;
922 err = chip::TLV::Utilities::Find(reader, ProfileTag(TestProfile_1, 1), tagReader);
923 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
925 err = tagReader.EnterContainer(outerContainerType);
926 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
930 err = tagReader.Next();
931 } while (err != CHIP_END_OF_TLV);
933 TestEnd<TLVReader>(inSuite, tagReader);
935 // Init a TLVUpdater using the TLVReader
936 err = updater.Init(tagReader, maxLen - dataLen);
937 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
943 err = chip::TLV::Utilities::Find(reader, ProfileTag(TestProfile_2, 2), tagReader);
944 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
946 // Test Find(recurse = true)
947 TLVReader tagReader2;
948 err = chip::TLV::Utilities::Find(reader, ProfileTag(TestProfile_2, 2), tagReader2, true);
949 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
951 // Test Find(recurse = false)
952 TLVReader tagReader3;
953 err = chip::TLV::Utilities::Find(reader, ProfileTag(TestProfile_2, 2), tagReader3, false);
954 NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_TLV_TAG_NOT_FOUND);
956 // Init a TLVUpdater using the TLVReader
957 err = updater.Init(tagReader, maxLen - dataLen);
958 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
960 TestNext<TLVUpdater>(inSuite, updater);
962 // Move the element without modification
963 TestMove(inSuite, updater);
966 // Put new values in the encoding using the updater
967 // Add <TestProfile_1, 2, false>
968 err = updater.PutBoolean(ProfileTag(TestProfile_1, 2), false);
969 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
971 // Add <TestProfile_2, 2, true>
972 err = updater.PutBoolean(ProfileTag(TestProfile_2, 2), true);
973 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
975 // Add a new container
977 TLVType outerContainerType1;
979 err = updater.StartContainer(ProfileTag(TestProfile_1, 1), kTLVType_Structure, outerContainerType1);
980 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
982 // Add <TestProfile_1, 2, true>
983 err = updater.PutBoolean(ProfileTag(TestProfile_1, 2), true);
984 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
986 // Add <TestProfile_1, 2, true>
987 err = updater.PutBoolean(ProfileTag(TestProfile_2, 2), false);
988 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
990 // Close the container
991 err = updater.EndContainer(outerContainerType1);
992 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
995 // Add another new container
997 TLVType outerContainerType1;
999 err = updater.StartContainer(ProfileTag(TestProfile_2, 1), kTLVType_Structure, outerContainerType1);
1000 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
1002 // Add <TestProfile_2, 2, false>
1003 err = updater.PutBoolean(ProfileTag(TestProfile_2, 2), false);
1004 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
1006 // Add <TestProfile_1, 2, true>
1007 err = updater.PutBoolean(ProfileTag(TestProfile_1, 2), true);
1008 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
1010 // Close the container
1011 err = updater.EndContainer(outerContainerType1);
1012 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
1015 // Move everything else unmodified
1016 updater.MoveUntilEnd();
1018 TestEnd<TLVUpdater>(inSuite, updater);
1020 err = updater.Finalize();
1021 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
1023 updatedLen = updater.GetLengthWritten();
1026 void AppendEncoding3(nlTestSuite * inSuite, uint8_t * buf, uint32_t dataLen, uint32_t maxLen, uint32_t & updatedLen)
1032 err = updater.Init(buf, dataLen, maxLen);
1033 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
1035 updater.SetImplicitProfileId(TestProfile_2);
1037 TestNext<TLVUpdater>(inSuite, updater);
1040 TLVType outerContainerType;
1042 TestAndEnterContainer<TLVUpdater>(inSuite, updater, kTLVType_Structure, ProfileTag(TestProfile_1, 1), outerContainerType);
1044 TestNext<TLVUpdater>(inSuite, updater);
1046 // Move the element without modification
1047 TestMove(inSuite, updater);
1049 // Put new value in the encoding using the updater
1050 // Add <TestProfile_2, 2, true>
1051 err = updater.PutBoolean(ProfileTag(TestProfile_2, 2), true);
1052 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
1054 TestEndAndExitContainer<TLVUpdater>(inSuite, updater, outerContainerType);
1057 TestEnd<TLVUpdater>(inSuite, updater);
1059 err = updater.Finalize();
1060 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
1062 updatedLen = updater.GetLengthWritten();
1065 void AppendEncoding4(nlTestSuite * inSuite, uint8_t * buf, uint32_t dataLen, uint32_t maxLen, uint32_t & updatedLen)
1071 err = updater.Init(buf, dataLen, maxLen);
1072 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
1074 updater.SetImplicitProfileId(TestProfile_2);
1076 // Add a new container
1078 TLVType outerContainerType;
1080 err = updater.StartContainer(ProfileTag(TestProfile_1, 1), kTLVType_Structure, outerContainerType);
1081 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
1083 // Add <TestProfile_1, 2, true>
1084 err = updater.PutBoolean(ProfileTag(TestProfile_2, 2), false);
1085 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
1087 // Close the container
1088 err = updater.EndContainer(outerContainerType);
1089 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
1092 err = updater.Finalize();
1093 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
1095 updatedLen = updater.GetLengthWritten();
1098 void DeleteEncoding5(nlTestSuite * inSuite, uint8_t * buf, uint32_t dataLen, uint32_t maxLen, uint32_t & updatedLen)
1104 err = updater.Init(buf, dataLen, maxLen);
1105 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
1107 updater.SetImplicitProfileId(TestProfile_2);
1109 TestNext<TLVUpdater>(inSuite, updater);
1112 TLVType outerContainerType;
1114 TestAndEnterContainer<TLVUpdater>(inSuite, updater, kTLVType_Structure, ProfileTag(TestProfile_1, 1), outerContainerType);
1116 TestNext<TLVUpdater>(inSuite, updater);
1118 TestMove(inSuite, updater);
1120 TestNext<TLVUpdater>(inSuite, updater);
1122 TestMove(inSuite, updater);
1124 TestNext<TLVUpdater>(inSuite, updater);
1126 // Get the value to inspect and skip writing it
1127 TestGet<TLVUpdater, bool>(inSuite, updater, kTLVType_Boolean, ProfileTag(TestProfile_1, 2), false);
1129 TestNext<TLVUpdater>(inSuite, updater);
1131 // Skip the next boolean type and don't copy by doing nothing
1133 TestNext<TLVUpdater>(inSuite, updater);
1135 // Read ahead into the next container and decide whether to skip or
1136 // not based on elements in the container
1139 TLVType containerType;
1141 updater.GetReader(reader);
1143 TestAndEnterContainer<TLVReader>(inSuite, reader, kTLVType_Structure, ProfileTag(TestProfile_1, 1), containerType);
1145 TestNext<TLVReader>(inSuite, reader);
1147 // If the container's first element has the tag <TestProfile_1, 2>
1148 // skip the whole container, and if NOT copy the container
1149 if (reader.GetTag() != ProfileTag(TestProfile_1, 2))
1150 TestMove(inSuite, updater);
1153 TestNext<TLVUpdater>(inSuite, updater);
1155 // Skip the next container and don't copy by doing nothing
1157 TestEndAndExitContainer<TLVUpdater>(inSuite, updater, outerContainerType);
1160 // Move everything else unmodified
1161 updater.MoveUntilEnd();
1163 TestEnd<TLVUpdater>(inSuite, updater);
1165 err = updater.Finalize();
1166 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
1168 updatedLen = updater.GetLengthWritten();
1171 void ReadAppendedEncoding2(nlTestSuite * inSuite, TLVReader & reader)
1173 TestNext<TLVReader>(inSuite, reader);
1178 TestAndOpenContainer(inSuite, reader, kTLVType_Structure, ProfileTag(TestProfile_1, 1), reader1);
1180 TestNext<TLVReader>(inSuite, reader1);
1182 TestGet<TLVReader, bool>(inSuite, reader1, kTLVType_Boolean, ProfileTag(TestProfile_1, 2), true);
1184 TestNext<TLVReader>(inSuite, reader1);
1186 TestGet<TLVReader, bool>(inSuite, reader1, kTLVType_Boolean, ProfileTag(TestProfile_2, 2), false);
1188 TestNext<TLVReader>(inSuite, reader1);
1190 TestGet<TLVReader, bool>(inSuite, reader1, kTLVType_Boolean, ProfileTag(TestProfile_1, 2), false);
1192 TestNext<TLVReader>(inSuite, reader1);
1194 TestGet<TLVReader, bool>(inSuite, reader1, kTLVType_Boolean, ProfileTag(TestProfile_2, 2), true);
1196 TestNext<TLVReader>(inSuite, reader1);
1201 TestAndOpenContainer(inSuite, reader1, kTLVType_Structure, ProfileTag(TestProfile_1, 1), reader2);
1203 TestNext<TLVReader>(inSuite, reader2);
1205 TestGet<TLVReader, bool>(inSuite, reader2, kTLVType_Boolean, ProfileTag(TestProfile_1, 2), true);
1207 TestNext<TLVReader>(inSuite, reader2);
1209 TestGet<TLVReader, bool>(inSuite, reader2, kTLVType_Boolean, ProfileTag(TestProfile_2, 2), false);
1211 TestEndAndCloseContainer(inSuite, reader1, reader2);
1214 TestNext<TLVReader>(inSuite, reader1);
1219 TestAndOpenContainer(inSuite, reader1, kTLVType_Structure, ProfileTag(TestProfile_2, 1), reader2);
1221 TestNext<TLVReader>(inSuite, reader2);
1223 TestGet<TLVReader, bool>(inSuite, reader2, kTLVType_Boolean, ProfileTag(TestProfile_2, 2), false);
1225 TestNext<TLVReader>(inSuite, reader2);
1227 TestGet<TLVReader, bool>(inSuite, reader2, kTLVType_Boolean, ProfileTag(TestProfile_1, 2), true);
1229 TestEndAndCloseContainer(inSuite, reader1, reader2);
1232 TestEndAndCloseContainer(inSuite, reader, reader1);
1235 TestNext<TLVReader>(inSuite, reader);
1240 TestAndOpenContainer(inSuite, reader, kTLVType_Structure, ProfileTag(TestProfile_2, 1), reader1);
1242 TestNext<TLVReader>(inSuite, reader1);
1244 TestGet<TLVReader, bool>(inSuite, reader1, kTLVType_Boolean, ProfileTag(TestProfile_2, 2), false);
1246 TestNext<TLVReader>(inSuite, reader1);
1248 TestGet<TLVReader, bool>(inSuite, reader1, kTLVType_Boolean, ProfileTag(TestProfile_1, 2), true);
1250 TestEndAndCloseContainer(inSuite, reader, reader1);
1253 TestEnd<TLVReader>(inSuite, reader);
1256 void ReadAppendedEncoding3(nlTestSuite * inSuite, TLVReader & reader)
1258 TestNext<TLVReader>(inSuite, reader);
1263 TestAndOpenContainer(inSuite, reader, kTLVType_Structure, ProfileTag(TestProfile_1, 1), reader1);
1265 TestNext<TLVReader>(inSuite, reader1);
1267 TestGet<TLVReader, bool>(inSuite, reader1, kTLVType_Boolean, ProfileTag(TestProfile_2, 2), false);
1269 TestNext<TLVReader>(inSuite, reader1);
1271 TestGet<TLVReader, bool>(inSuite, reader1, kTLVType_Boolean, ProfileTag(TestProfile_2, 2), true);
1273 TestEndAndCloseContainer(inSuite, reader, reader1);
1276 TestEnd<TLVReader>(inSuite, reader);
1279 void ReadAppendedEncoding4(nlTestSuite * inSuite, TLVReader & reader)
1281 TestNext<TLVReader>(inSuite, reader);
1286 TestAndOpenContainer(inSuite, reader, kTLVType_Structure, ProfileTag(TestProfile_1, 1), reader1);
1288 TestNext<TLVReader>(inSuite, reader1);
1290 TestGet<TLVReader, bool>(inSuite, reader1, kTLVType_Boolean, ProfileTag(TestProfile_2, 2), false);
1292 TestEndAndCloseContainer(inSuite, reader, reader1);
1295 TestEnd<TLVReader>(inSuite, reader);
1298 void ReadDeletedEncoding5(nlTestSuite * inSuite, TLVReader & reader)
1300 TestNext<TLVReader>(inSuite, reader);
1305 TestAndOpenContainer(inSuite, reader, kTLVType_Structure, ProfileTag(TestProfile_1, 1), reader1);
1307 TestNext<TLVReader>(inSuite, reader1);
1309 TestGet<TLVReader, bool>(inSuite, reader1, kTLVType_Boolean, ProfileTag(TestProfile_1, 2), true);
1311 TestNext<TLVReader>(inSuite, reader1);
1313 TestGet<TLVReader, bool>(inSuite, reader1, kTLVType_Boolean, ProfileTag(TestProfile_2, 2), false);
1315 TestEndAndCloseContainer(inSuite, reader, reader1);
1318 TestNext<TLVReader>(inSuite, reader);
1323 TestAndOpenContainer(inSuite, reader, kTLVType_Structure, ProfileTag(TestProfile_2, 1), reader1);
1325 TestNext<TLVReader>(inSuite, reader1);
1327 TestGet<TLVReader, bool>(inSuite, reader1, kTLVType_Boolean, ProfileTag(TestProfile_2, 2), false);
1329 TestNext<TLVReader>(inSuite, reader1);
1331 TestGet<TLVReader, bool>(inSuite, reader1, kTLVType_Boolean, ProfileTag(TestProfile_1, 2), true);
1333 TestEndAndCloseContainer(inSuite, reader, reader1);
1336 TestEnd<TLVReader>(inSuite, reader);
1340 * Test Simple Write and Reader
1342 void CheckSimpleWriteRead(nlTestSuite * inSuite, void * inContext)
1347 uint32_t remainingFreedLen;
1349 writer.Init(buf, sizeof(buf));
1350 writer.ImplicitProfileId = TestProfile_2;
1352 remainingFreedLen = writer.GetRemainingFreeLength();
1353 NL_TEST_ASSERT(inSuite, sizeof(buf) == remainingFreedLen);
1355 WriteEncoding1(inSuite, writer);
1357 uint32_t encodedLen = writer.GetLengthWritten();
1359 #ifdef DUMP_ENCODING
1360 for (uint32_t i = 0; i < encodedLen; i++)
1362 if (i != 0 && i % 16 == 0)
1364 printf("0x%02X, ", buf[i]);
1369 NL_TEST_ASSERT(inSuite, encodedLen == sizeof(Encoding1));
1370 NL_TEST_ASSERT(inSuite, memcmp(buf, Encoding1, encodedLen) == 0);
1372 reader.Init(buf, encodedLen);
1373 reader.ImplicitProfileId = TestProfile_2;
1375 ReadEncoding1(inSuite, reader);
1379 * Log the specified message in the form of @a aFormat.
1381 * @param[in] aFormat A pointer to a NULL-terminated C string with
1382 * C Standard Library-style format specifiers
1383 * containing the log message to be formatted and
1385 * @param[in] ... An argument list whose elements should correspond
1386 * to the format specifiers in @a aFormat.
1389 void SimpleDumpWriter(const char * aFormat, ...)
1393 va_start(args, aFormat);
1395 vprintf(aFormat, args);
1401 * Test Pretty Printer
1403 void CheckPrettyPrinter(nlTestSuite * inSuite, void * inContext)
1409 writer.Init(buf, sizeof(buf));
1410 writer.ImplicitProfileId = TestProfile_2;
1412 WriteEncoding1(inSuite, writer);
1414 uint32_t encodedLen = writer.GetLengthWritten();
1416 NL_TEST_ASSERT(inSuite, encodedLen == sizeof(Encoding1));
1417 NL_TEST_ASSERT(inSuite, memcmp(buf, Encoding1, encodedLen) == 0);
1419 reader.Init(buf, encodedLen);
1420 reader.ImplicitProfileId = TestProfile_2;
1421 chip::TLV::Debug::Dump(reader, SimpleDumpWriter);
1427 void CheckDataMacro(nlTestSuite * inSuite, void * inContext)
1429 NL_TEST_ASSERT(inSuite, sizeof(Encoding1_DataMacro) == sizeof(Encoding1));
1430 NL_TEST_ASSERT(inSuite, memcmp(Encoding1, Encoding1_DataMacro, sizeof(Encoding1)) == 0);
1434 writer.Init(buf, sizeof(buf));
1435 writer.ImplicitProfileId = TestProfile_2;
1436 WriteEncoding5(inSuite, writer);
1437 uint32_t encodedLen = writer.GetLengthWritten();
1439 NL_TEST_ASSERT(inSuite, sizeof(Encoding5_DataMacro) == encodedLen);
1440 NL_TEST_ASSERT(inSuite, memcmp(buf, Encoding5_DataMacro, encodedLen) == 0);
1443 static CHIP_ERROR NullIterateHandler(const TLVReader & aReader, size_t aDepth, void * aContext)
1449 return CHIP_NO_ERROR;
1452 static CHIP_ERROR FindContainerWithElement(const TLVReader & aReader, size_t aDepth, void * aContext)
1456 uint64_t * tag = static_cast<uint64_t *>(aContext);
1457 CHIP_ERROR err = CHIP_NO_ERROR;
1458 TLVType containerType;
1460 reader.Init(aReader);
1462 if (TLVTypeIsContainer(reader.GetType()))
1464 ReturnErrorOnFailure(reader.EnterContainer(containerType));
1466 err = chip::TLV::Utilities::Find(reader, *tag, result, false);
1468 // Map a successful find (CHIP_NO_ERROR) onto a signal that the element has been found.
1469 if (err == CHIP_NO_ERROR)
1471 err = CHIP_ERROR_MAX;
1473 // Map a failed find attempt to NO_ERROR
1474 else if (err == CHIP_ERROR_TLV_TAG_NOT_FOUND)
1476 err = CHIP_NO_ERROR;
1483 * Test CHIP TLV Utilities
1485 void CheckCHIPTLVUtilities(nlTestSuite * inSuite, void * inContext)
1489 TLVReader reader, reader1;
1490 CHIP_ERROR err = CHIP_NO_ERROR;
1492 writer.Init(buf, sizeof(buf));
1493 writer.ImplicitProfileId = TestProfile_2;
1495 WriteEncoding1(inSuite, writer);
1497 uint32_t encodedLen = writer.GetLengthWritten();
1499 NL_TEST_ASSERT(inSuite, encodedLen == sizeof(Encoding1));
1500 NL_TEST_ASSERT(inSuite, memcmp(buf, Encoding1, encodedLen) == 0);
1502 reader.Init(buf, encodedLen);
1503 reader.ImplicitProfileId = TestProfile_2;
1505 reader1.Init(reader);
1506 err = reader1.Next();
1507 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
1510 TLVReader tagReader;
1511 err = chip::TLV::Utilities::Find(reader, ProfileTag(TestProfile_2, 65536), tagReader);
1512 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
1514 // Find with reader positioned "on" the element of interest
1515 err = chip::TLV::Utilities::Find(reader1, ProfileTag(TestProfile_1, 1), tagReader);
1516 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
1518 // Find a tag that's not present
1519 err = chip::TLV::Utilities::Find(reader, ProfileTag(TestProfile_2, 1024), tagReader);
1520 NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_TLV_TAG_NOT_FOUND);
1522 // Find with a predicate
1526 writer.Init(buf1, sizeof(buf1));
1527 writer.ImplicitProfileId = TestProfile_2;
1529 WriteEncoding2(inSuite, writer);
1531 // Initialize a reader
1532 reader1.Init(buf1, writer.GetLengthWritten());
1533 reader1.ImplicitProfileId = TestProfile_2;
1535 // position the reader on the first element
1537 uint64_t tag = ProfileTag(TestProfile_1, 1);
1538 err = chip::TLV::Utilities::Find(reader1, FindContainerWithElement, &tag, tagReader, false);
1539 NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_TLV_TAG_NOT_FOUND);
1541 tag = ProfileTag(TestProfile_2, 2);
1542 err = chip::TLV::Utilities::Find(reader1, FindContainerWithElement, &tag, tagReader, false);
1543 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
1544 NL_TEST_ASSERT(inSuite, tagReader.GetType() == kTLVType_Structure);
1545 NL_TEST_ASSERT(inSuite, tagReader.GetTag() == ProfileTag(TestProfile_1, 1));
1547 // Position the reader on the second element
1549 err = chip::TLV::Utilities::Find(reader1, FindContainerWithElement, &tag, tagReader, false);
1550 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
1551 NL_TEST_ASSERT(inSuite, tagReader.GetType() == kTLVType_Structure);
1552 NL_TEST_ASSERT(inSuite, tagReader.GetTag() == ProfileTag(TestProfile_2, 1));
1557 const size_t expectedCount = 18;
1558 reader1.Init(reader);
1561 err = chip::TLV::Utilities::Count(reader, count);
1562 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
1563 NL_TEST_ASSERT(inSuite, count == expectedCount);
1565 // Count with reader already positioned "on" the first element in the encoding
1566 err = chip::TLV::Utilities::Count(reader1, count);
1567 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
1568 NL_TEST_ASSERT(inSuite, count == expectedCount);
1571 err = chip::TLV::Utilities::Iterate(reader, NullIterateHandler, nullptr);
1572 NL_TEST_ASSERT(inSuite, err == CHIP_END_OF_TLV);
1576 * Test CHIP TLV Empty Find
1578 void CheckCHIPTLVEmptyFind(nlTestSuite * inSuite, void * inContext)
1583 CHIP_ERROR err = CHIP_NO_ERROR;
1585 writer.Init(buf, sizeof(buf));
1586 writer.ImplicitProfileId = TestProfile_2;
1588 WriteEmptyEncoding(inSuite, writer);
1590 uint32_t encodedLen = writer.GetLengthWritten();
1592 reader.Init(buf, encodedLen);
1593 reader.ImplicitProfileId = TestProfile_2;
1595 // Find the empty container
1596 TLVReader tagReader;
1597 err = chip::TLV::Utilities::Find(reader, ProfileTag(TestProfile_1, 256), tagReader);
1598 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
1602 uint8_t Encoding2[] =
1605 0xD5, 0xBB, 0xAA, 0xDD, 0xCC, 0x01, 0x00,
1606 0xC9, 0xBB, 0xAA, 0xDD, 0xCC, 0x02, 0x00,
1612 0xC9, 0xBB, 0xAA, 0xDD, 0xCC, 0x02, 0x00,
1616 uint8_t AppendedEncoding2[] =
1619 0xD5, 0xBB, 0xAA, 0xDD, 0xCC, 0x01, 0x00,
1620 0xC9, 0xBB, 0xAA, 0xDD, 0xCC, 0x02, 0x00,
1622 0xC8, 0xBB, 0xAA, 0xDD, 0xCC, 0x02, 0x00,
1624 0xD5, 0xBB, 0xAA, 0xDD, 0xCC, 0x01, 0x00,
1625 0xC9, 0xBB, 0xAA, 0xDD, 0xCC, 0x02, 0x00,
1630 0xC9, 0xBB, 0xAA, 0xDD, 0xCC, 0x02, 0x00,
1636 0xC9, 0xBB, 0xAA, 0xDD, 0xCC, 0x02, 0x00,
1641 void WriteAppendReadTest0(nlTestSuite * inSuite)
1644 uint32_t updatedLen;
1649 writer.Init(buf, sizeof(buf));
1650 writer.ImplicitProfileId = TestProfile_2;
1652 WriteEncoding2(inSuite, writer);
1654 uint32_t encodedLen = writer.GetLengthWritten();
1656 #ifdef DUMP_ENCODING
1657 printf("Initial encoding:\n");
1658 for (uint32_t i = 0; i < encodedLen; i++)
1660 if (i != 0 && i % 16 == 0)
1662 printf("0x%02X, ", buf[i]);
1667 NL_TEST_ASSERT(inSuite, encodedLen == sizeof(Encoding2));
1668 NL_TEST_ASSERT(inSuite, memcmp(buf, Encoding2, encodedLen) == 0);
1670 // Append new data into encoding
1671 AppendEncoding2(inSuite, buf, encodedLen, sizeof(buf), updatedLen);
1673 #ifdef DUMP_ENCODING
1674 printf("Updated encoding:\n");
1675 for (uint32_t i = 0; i < updatedLen; i++)
1677 if (i != 0 && i % 16 == 0)
1679 printf("0x%02X, ", buf[i]);
1684 NL_TEST_ASSERT(inSuite, updatedLen == sizeof(AppendedEncoding2));
1685 NL_TEST_ASSERT(inSuite, memcmp(buf, AppendedEncoding2, updatedLen) == 0);
1687 reader.Init(buf, updatedLen);
1688 reader.ImplicitProfileId = TestProfile_2;
1690 ReadAppendedEncoding2(inSuite, reader);
1693 void WriteFindAppendReadTest(nlTestSuite * inSuite, bool findContainer)
1696 uint32_t updatedLen;
1701 writer.Init(buf, sizeof(buf));
1702 writer.ImplicitProfileId = TestProfile_2;
1704 WriteEncoding2(inSuite, writer);
1706 uint32_t encodedLen = writer.GetLengthWritten();
1708 #ifdef DUMP_ENCODING
1709 printf("Initial encoding:\n");
1710 for (uint32_t i = 0; i < encodedLen; i++)
1712 if (i != 0 && i % 16 == 0)
1714 printf("0x%02X, ", buf[i]);
1719 NL_TEST_ASSERT(inSuite, encodedLen == sizeof(Encoding2));
1720 NL_TEST_ASSERT(inSuite, memcmp(buf, Encoding2, encodedLen) == 0);
1722 // Append new data into encoding
1723 FindAppendEncoding2(inSuite, buf, encodedLen, sizeof(buf), updatedLen, findContainer);
1725 #ifdef DUMP_ENCODING
1726 printf("Updated encoding:\n");
1727 for (uint32_t i = 0; i < updatedLen; i++)
1729 if (i != 0 && i % 16 == 0)
1731 printf("0x%02X, ", buf[i]);
1736 NL_TEST_ASSERT(inSuite, updatedLen == sizeof(AppendedEncoding2));
1737 NL_TEST_ASSERT(inSuite, memcmp(buf, AppendedEncoding2, updatedLen) == 0);
1739 reader.Init(buf, updatedLen);
1740 reader.ImplicitProfileId = TestProfile_2;
1742 ReadAppendedEncoding2(inSuite, reader);
1746 uint8_t Encoding3[] =
1749 0xD5, 0xBB, 0xAA, 0xDD, 0xCC, 0x01, 0x00,
1754 uint8_t AppendedEncoding3[] =
1757 0xD5, 0xBB, 0xAA, 0xDD, 0xCC, 0x01, 0x00,
1764 void WriteAppendReadTest1(nlTestSuite * inSuite)
1767 uint32_t updatedLen;
1772 writer.Init(buf, sizeof(buf));
1773 writer.ImplicitProfileId = TestProfile_2;
1775 WriteEncoding3(inSuite, writer);
1777 uint32_t encodedLen = writer.GetLengthWritten();
1779 #ifdef DUMP_ENCODING
1780 printf("Initial encoding:\n");
1781 for (uint32_t i = 0; i < encodedLen; i++)
1783 if (i != 0 && i % 16 == 0)
1785 printf("0x%02X, ", buf[i]);
1790 NL_TEST_ASSERT(inSuite, encodedLen == sizeof(Encoding3));
1791 NL_TEST_ASSERT(inSuite, memcmp(buf, Encoding3, encodedLen) == 0);
1793 // Append new data into encoding
1794 AppendEncoding3(inSuite, buf, encodedLen, sizeof(buf), updatedLen);
1796 #ifdef DUMP_ENCODING
1797 printf("Updated encoding:\n");
1798 for (uint32_t i = 0; i < updatedLen; i++)
1800 if (i != 0 && i % 16 == 0)
1802 printf("0x%02X, ", buf[i]);
1807 NL_TEST_ASSERT(inSuite, updatedLen == sizeof(AppendedEncoding3));
1808 NL_TEST_ASSERT(inSuite, memcmp(buf, AppendedEncoding3, updatedLen) == 0);
1810 reader.Init(buf, updatedLen);
1811 reader.ImplicitProfileId = TestProfile_2;
1813 ReadAppendedEncoding3(inSuite, reader);
1817 uint8_t AppendedEncoding4[] =
1820 0xD5, 0xBB, 0xAA, 0xDD, 0xCC, 0x01, 0x00,
1826 void AppendReadTest(nlTestSuite * inSuite)
1829 uint32_t updatedLen;
1831 memset(buf, 0, sizeof(buf));
1833 #ifdef DUMP_ENCODING
1834 printf("Initial encoding:\n");
1835 for (uint32_t i = 0; i < sizeof(buf); i++)
1837 if (i != 0 && i % 16 == 0)
1839 printf("0x%02X, ", buf[i]);
1844 // Append new data to encoding
1845 AppendEncoding4(inSuite, buf, 0, sizeof(buf), updatedLen);
1847 #ifdef DUMP_ENCODING
1848 printf("Updated encoding:\n");
1849 for (uint32_t i = 0; i < updatedLen; i++)
1851 if (i != 0 && i % 16 == 0)
1853 printf("0x%02X, ", buf[i]);
1858 NL_TEST_ASSERT(inSuite, updatedLen == sizeof(AppendedEncoding4));
1859 NL_TEST_ASSERT(inSuite, memcmp(buf, AppendedEncoding4, updatedLen) == 0);
1862 reader.Init(buf, updatedLen);
1863 reader.ImplicitProfileId = TestProfile_2;
1865 ReadAppendedEncoding4(inSuite, reader);
1869 uint8_t Encoding5[] =
1872 0xD5, 0xBB, 0xAA, 0xDD, 0xCC, 0x01, 0x00,
1873 0xC9, 0xBB, 0xAA, 0xDD, 0xCC, 0x02, 0x00,
1875 0xC8, 0xBB, 0xAA, 0xDD, 0xCC, 0x02, 0x00,
1877 0xD5, 0xBB, 0xAA, 0xDD, 0xCC, 0x01, 0x00,
1878 0xC9, 0xBB, 0xAA, 0xDD, 0xCC, 0x02, 0x00,
1883 0xC9, 0xBB, 0xAA, 0xDD, 0xCC, 0x02, 0x00,
1889 0xC9, 0xBB, 0xAA, 0xDD, 0xCC, 0x02, 0x00,
1893 uint8_t DeletedEncoding5[] =
1896 0xD5, 0xBB, 0xAA, 0xDD, 0xCC, 0x01, 0x00,
1897 0xC9, 0xBB, 0xAA, 0xDD, 0xCC, 0x02, 0x00,
1903 0xC9, 0xBB, 0xAA, 0xDD, 0xCC, 0x02, 0x00,
1908 void WriteDeleteReadTest(nlTestSuite * inSuite)
1911 uint32_t updatedLen;
1916 writer.Init(buf, sizeof(buf));
1917 writer.ImplicitProfileId = TestProfile_2;
1919 WriteEncoding5(inSuite, writer);
1921 uint32_t encodedLen = writer.GetLengthWritten();
1923 #ifdef DUMP_ENCODING
1924 for (uint32_t i = 0; i < encodedLen; i++)
1926 if (i != 0 && i % 16 == 0)
1928 printf("0x%02X, ", buf[i]);
1933 NL_TEST_ASSERT(inSuite, encodedLen == sizeof(Encoding5));
1934 NL_TEST_ASSERT(inSuite, memcmp(buf, Encoding5, encodedLen) == 0);
1936 // Delete some elements from the encoding
1937 DeleteEncoding5(inSuite, buf, encodedLen, sizeof(buf), updatedLen);
1939 NL_TEST_ASSERT(inSuite, updatedLen == sizeof(DeletedEncoding5));
1940 NL_TEST_ASSERT(inSuite, memcmp(buf, DeletedEncoding5, updatedLen) == 0);
1942 reader.Init(buf, updatedLen);
1943 reader.ImplicitProfileId = TestProfile_2;
1945 ReadDeletedEncoding5(inSuite, reader);
1949 * Test Packet Buffer
1951 void CheckPacketBuffer(nlTestSuite * inSuite, void * inContext)
1953 System::PacketBufferHandle buf = System::PacketBufferHandle::New(sizeof(Encoding1), 0);
1954 System::PacketBufferTLVWriter writer;
1955 System::PacketBufferTLVReader reader;
1957 writer.Init(buf.Retain());
1958 writer.ImplicitProfileId = TestProfile_2;
1960 WriteEncoding1(inSuite, writer);
1962 TestBufferContents(inSuite, buf, Encoding1, sizeof(Encoding1));
1964 reader.Init(buf.Retain());
1965 reader.ImplicitProfileId = TestProfile_2;
1967 ReadEncoding1(inSuite, reader);
1969 reader.Init(buf.Retain(), buf->MaxDataLength());
1970 reader.ImplicitProfileId = TestProfile_2;
1972 ReadEncoding1(inSuite, reader);
1975 CHIP_ERROR CountEvictedMembers(CHIPCircularTLVBuffer & inBuffer, void * inAppData, TLVReader & inReader)
1977 TestTLVContext * context = static_cast<TestTLVContext *>(inAppData);
1980 // "Process" the first element in the reader
1981 err = inReader.Next();
1982 NL_TEST_ASSERT(context->mSuite, err == CHIP_NO_ERROR);
1984 err = inReader.Skip();
1985 NL_TEST_ASSERT(context->mSuite, err == CHIP_NO_ERROR);
1987 context->mEvictionCount++;
1988 context->mEvictedBytes += inReader.GetLengthRead();
1990 return CHIP_NO_ERROR;
1993 void CheckCircularTLVBufferSimple(nlTestSuite * inSuite, void * inContext)
1995 // Write 40 bytes as 4 separate events into a 30 byte buffer. On
1996 // completion of the test, the buffer should contain 2 elements
1997 // and 2 elements should have been evicted in the last call to
2000 uint8_t backingStore[30];
2001 CircularTLVWriter writer;
2002 CircularTLVReader reader;
2003 TestTLVContext * context = static_cast<TestTLVContext *>(inContext);
2004 CHIPCircularTLVBuffer buffer(backingStore, 30);
2005 writer.Init(buffer);
2006 writer.ImplicitProfileId = TestProfile_2;
2008 context->mEvictionCount = 0;
2009 context->mEvictedBytes = 0;
2011 buffer.mProcessEvictedElement = CountEvictedMembers;
2012 buffer.mAppData = inContext;
2014 writer.PutBoolean(ProfileTag(TestProfile_1, 2), true);
2016 WriteEncoding3(inSuite, writer);
2018 WriteEncoding3(inSuite, writer);
2020 WriteEncoding3(inSuite, writer);
2022 NL_TEST_ASSERT(inSuite, context->mEvictionCount == 2);
2023 NL_TEST_ASSERT(inSuite, context->mEvictedBytes == 18);
2024 NL_TEST_ASSERT(inSuite, buffer.DataLength() == 22);
2025 NL_TEST_ASSERT(inSuite, (buffer.DataLength() + context->mEvictedBytes) == writer.GetLengthWritten());
2027 // At this point the buffer should contain 2 instances of Encoding3.
2028 reader.Init(buffer);
2029 reader.ImplicitProfileId = TestProfile_2;
2031 TestNext<TLVReader>(inSuite, reader);
2033 ReadEncoding3(inSuite, reader);
2035 TestNext<TLVReader>(inSuite, reader);
2037 ReadEncoding3(inSuite, reader);
2039 // Check that the reader is out of data
2040 TestEnd<TLVReader>(inSuite, reader);
2043 void CheckCircularTLVBufferStartMidway(nlTestSuite * inSuite, void * inContext)
2045 // Write 40 bytes as 4 separate events into a 30 byte buffer. On
2046 // completion of the test, the buffer should contain 2 elements
2047 // and 2 elements should have been evicted in the last call to
2050 uint8_t backingStore[30];
2051 CircularTLVWriter writer;
2052 CircularTLVReader reader;
2053 TestTLVContext * context = static_cast<TestTLVContext *>(inContext);
2054 CHIPCircularTLVBuffer buffer(backingStore, 30, &(backingStore[15]));
2055 writer.Init(buffer);
2056 writer.ImplicitProfileId = TestProfile_2;
2058 context->mEvictionCount = 0;
2059 context->mEvictedBytes = 0;
2061 buffer.mProcessEvictedElement = CountEvictedMembers;
2062 buffer.mAppData = inContext;
2064 writer.PutBoolean(ProfileTag(TestProfile_1, 2), true);
2066 WriteEncoding3(inSuite, writer);
2068 WriteEncoding3(inSuite, writer);
2070 WriteEncoding3(inSuite, writer);
2072 NL_TEST_ASSERT(inSuite, context->mEvictionCount == 2);
2073 NL_TEST_ASSERT(inSuite, context->mEvictedBytes == 18);
2074 NL_TEST_ASSERT(inSuite, buffer.DataLength() == 22);
2075 NL_TEST_ASSERT(inSuite, (buffer.DataLength() + context->mEvictedBytes) == writer.GetLengthWritten());
2077 // At this point the buffer should contain 2 instances of Encoding3.
2078 reader.Init(buffer);
2079 reader.ImplicitProfileId = TestProfile_2;
2081 TestNext<TLVReader>(inSuite, reader);
2083 ReadEncoding3(inSuite, reader);
2085 TestNext<TLVReader>(inSuite, reader);
2087 ReadEncoding3(inSuite, reader);
2089 // Check that the reader is out of data
2090 TestEnd<TLVReader>(inSuite, reader);
2093 void CheckCircularTLVBufferEvictStraddlingEvent(nlTestSuite * inSuite, void * inContext)
2095 // Write 95 bytes to the buffer as 9 different TLV elements: 1
2096 // 7-byte element and 8 11-byte elements.
2097 // On completion of the test, the buffer should contain 2 elements
2098 // and 7 elements should have been evicted in the last call to
2101 TestTLVContext * context = static_cast<TestTLVContext *>(inContext);
2102 uint8_t backingStore[30];
2103 CircularTLVWriter writer;
2104 CircularTLVReader reader;
2105 CHIPCircularTLVBuffer buffer(backingStore, 30);
2106 writer.Init(buffer);
2107 writer.ImplicitProfileId = TestProfile_2;
2109 context->mEvictionCount = 0;
2110 context->mEvictedBytes = 0;
2112 buffer.mProcessEvictedElement = CountEvictedMembers;
2113 buffer.mAppData = inContext;
2115 writer.PutBoolean(ProfileTag(TestProfile_1, 2), true);
2117 WriteEncoding3(inSuite, writer);
2119 WriteEncoding3(inSuite, writer);
2121 WriteEncoding3(inSuite, writer);
2123 WriteEncoding3(inSuite, writer);
2125 // the write below will evict an element that straddles the buffer boundary.
2126 WriteEncoding3(inSuite, writer);
2128 WriteEncoding3(inSuite, writer);
2130 WriteEncoding3(inSuite, writer);
2132 WriteEncoding3(inSuite, writer);
2134 NL_TEST_ASSERT(inSuite,
2135 writer.GetLengthWritten() ==
2136 (8 * 11 + 7)); // 8 writes of Encoding3 (11 bytes each) and 7 bytes for the initial boolean.
2137 NL_TEST_ASSERT(inSuite, buffer.DataLength() == 22);
2138 NL_TEST_ASSERT(inSuite, (buffer.DataLength() + context->mEvictedBytes) == writer.GetLengthWritten());
2139 NL_TEST_ASSERT(inSuite, context->mEvictionCount == 7);
2141 // At this point the buffer should contain 2 instances of Encoding3.
2142 reader.Init(buffer);
2143 reader.ImplicitProfileId = TestProfile_2;
2145 TestNext<TLVReader>(inSuite, reader);
2147 ReadEncoding3(inSuite, reader);
2149 TestNext<TLVReader>(inSuite, reader);
2151 ReadEncoding3(inSuite, reader);
2153 // Check that the reader is out of data
2154 TestEnd<TLVReader>(inSuite, reader);
2157 void CheckCircularTLVBufferEdge(nlTestSuite * inSuite, void * inContext)
2159 TestTLVContext * context = static_cast<TestTLVContext *>(inContext);
2161 uint8_t backingStore[7];
2162 uint8_t backingStore1[14];
2163 CircularTLVWriter writer;
2164 CircularTLVReader reader;
2167 CHIPCircularTLVBuffer buffer(backingStore, sizeof(backingStore));
2168 CHIPCircularTLVBuffer buffer1(backingStore1, sizeof(backingStore1));
2169 writer.Init(buffer);
2170 writer.ImplicitProfileId = TestProfile_2;
2172 context->mEvictionCount = 0;
2173 context->mEvictedBytes = 0;
2175 buffer.mProcessEvictedElement = CountEvictedMembers;
2176 buffer.mAppData = inContext;
2178 // Test eviction for an element that fits in the underlying buffer exactly
2179 err = writer.PutBoolean(ProfileTag(TestProfile_1, 2), true);
2180 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
2182 err = writer.PutBoolean(ProfileTag(TestProfile_1, 2), false);
2183 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
2185 err = writer.Finalize();
2186 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
2187 // At this point the buffer should contain only the boolean we just wrote
2188 reader.Init(buffer);
2189 reader.ImplicitProfileId = TestProfile_2;
2191 TestNext<TLVReader>(inSuite, reader);
2192 TestGet<TLVReader, bool>(inSuite, reader, kTLVType_Boolean, ProfileTag(TestProfile_1, 2), false);
2194 // Check that the reader is out of data
2195 TestEnd<TLVReader>(inSuite, reader);
2197 // verify that an element larger than the underlying buffer fails out.
2198 err = writer.OpenContainer(ProfileTag(TestProfile_1, 1), kTLVType_Structure, writer1);
2199 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
2201 err = writer1.PutBoolean(ProfileTag(TestProfile_2, 2), false);
2202 NL_TEST_ASSERT(inSuite, err == CHIP_END_OF_TLV);
2204 // Verify reader correctness
2206 // Write an element that takes half of the buffer, and evict it.
2207 // Do it 2 times, so we test what happens when the head is at the
2208 // middle and at the end of the buffer but the buffer is empty.
2210 for (i = 0; i < 2; i++)
2212 writer.Init(buffer1);
2213 writer.ImplicitProfileId = TestProfile_2;
2215 err = writer.PutBoolean(ProfileTag(TestProfile_1, 2), true);
2216 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
2218 err = writer.Finalize();
2219 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
2221 reader.Init(buffer1);
2222 reader.ImplicitProfileId = TestProfile_2;
2224 TestNext<TLVReader>(inSuite, reader);
2225 TestGet<TLVReader, bool>(inSuite, reader, kTLVType_Boolean, ProfileTag(TestProfile_1, 2), true);
2226 TestEnd<TLVReader>(inSuite, reader);
2228 buffer1.EvictHead();
2230 reader.Init(buffer1);
2231 reader.ImplicitProfileId = TestProfile_2;
2232 TestEnd<TLVReader>(inSuite, reader);
2235 writer.Init(buffer1);
2236 writer.ImplicitProfileId = TestProfile_2;
2238 context->mEvictionCount = 0;
2239 context->mEvictedBytes = 0;
2241 buffer1.mProcessEvictedElement = CountEvictedMembers;
2242 buffer1.mAppData = inContext;
2244 // Two elements fit in the buffer exactly
2245 err = writer.PutBoolean(ProfileTag(TestProfile_1, 2), true);
2246 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
2248 err = writer.PutBoolean(ProfileTag(TestProfile_1, 2), false);
2249 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
2251 err = writer.Finalize();
2253 // Verify that we can read out two elements from the buffer
2254 reader.Init(buffer1);
2255 reader.ImplicitProfileId = TestProfile_2;
2257 TestNext<TLVReader>(inSuite, reader);
2258 TestGet<TLVReader, bool>(inSuite, reader, kTLVType_Boolean, ProfileTag(TestProfile_1, 2), true);
2260 TestNext<TLVReader>(inSuite, reader);
2261 TestGet<TLVReader, bool>(inSuite, reader, kTLVType_Boolean, ProfileTag(TestProfile_1, 2), false);
2263 TestEnd<TLVReader>(inSuite, reader);
2265 // Check that the eviction works as expected
2267 buffer1.EvictHead();
2269 // At this point the buffer should contain only the second boolean
2270 reader.Init(buffer1);
2271 reader.ImplicitProfileId = TestProfile_2;
2273 TestNext<TLVReader>(inSuite, reader);
2274 TestGet<TLVReader, bool>(inSuite, reader, kTLVType_Boolean, ProfileTag(TestProfile_1, 2), false);
2276 // Check that the reader is out of data
2277 TestEnd<TLVReader>(inSuite, reader);
2279 // Write another boolean, verify that the buffer is full and contains two booleans
2281 writer.Init(buffer1);
2282 writer.ImplicitProfileId = TestProfile_2;
2284 err = writer.PutBoolean(ProfileTag(TestProfile_1, 2), true);
2285 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
2287 err = writer.Finalize();
2288 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
2290 // Verify that we can read out two elements from the buffer
2291 reader.Init(buffer1);
2292 reader.ImplicitProfileId = TestProfile_2;
2294 TestNext<TLVReader>(inSuite, reader);
2295 TestGet<TLVReader, bool>(inSuite, reader, kTLVType_Boolean, ProfileTag(TestProfile_1, 2), false);
2297 TestNext<TLVReader>(inSuite, reader);
2298 TestGet<TLVReader, bool>(inSuite, reader, kTLVType_Boolean, ProfileTag(TestProfile_1, 2), true);
2300 TestEnd<TLVReader>(inSuite, reader);
2302 // Evict the elements from the buffer, verfiy that we have an
2303 // empty reader on our hands
2305 buffer1.EvictHead();
2306 buffer1.EvictHead();
2308 reader.Init(buffer1);
2309 reader.ImplicitProfileId = TestProfile_2;
2311 TestEnd<TLVReader>(inSuite, reader);
2313 void CheckCHIPTLVPutStringF(nlTestSuite * inSuite, void * inContext)
2315 const size_t bufsize = 24;
2316 char strBuffer[bufsize];
2317 char valStr[bufsize];
2318 uint8_t backingStore[bufsize];
2322 CHIP_ERROR err = CHIP_NO_ERROR;
2324 writer.Init(backingStore, bufsize);
2325 snprintf(strBuffer, sizeof(strBuffer), "Sample string %zu", num);
2327 err = writer.PutStringF(ProfileTag(TestProfile_1, 1), "Sample string %zu", num);
2328 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
2330 err = writer.Finalize();
2331 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
2333 reader.Init(backingStore, writer.GetLengthWritten());
2334 err = reader.Next();
2335 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
2337 err = reader.GetString(valStr, 256);
2338 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
2340 NL_TEST_ASSERT(inSuite, strncmp(valStr, strBuffer, 256) == 0);
2343 void CheckCHIPTLVPutStringFCircular(nlTestSuite * inSuite, void * inContext)
2345 const size_t bufsize = 40;
2346 char strBuffer[bufsize];
2347 char valStr[bufsize];
2348 uint8_t backingStore[bufsize];
2349 CircularTLVWriter writer;
2350 CircularTLVReader reader;
2351 CHIPCircularTLVBuffer buffer(backingStore, bufsize);
2353 CHIP_ERROR err = CHIP_NO_ERROR;
2355 // Initial test: Verify that a straight printf works as expected into continuous buffer.
2357 writer.Init(buffer);
2358 snprintf(strBuffer, sizeof(strBuffer), "Sample string %zu", num);
2360 err = writer.PutBoolean(ProfileTag(TestProfile_1, 2), true);
2361 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
2363 err = writer.Finalize();
2364 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
2366 err = writer.PutStringF(ProfileTag(TestProfile_1, 1), "Sample string %zu", num);
2367 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
2369 err = writer.Finalize();
2370 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
2372 reader.Init(buffer);
2374 // Skip over the initial element
2375 err = reader.Next();
2376 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
2378 err = reader.Next();
2379 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
2381 err = reader.GetString(valStr, bufsize);
2382 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
2384 NL_TEST_ASSERT(inSuite, strncmp(valStr, strBuffer, bufsize) == 0);
2386 // Verify that the PutStringF will handle correctly the case with the discontinuous buffer
2387 // This print will both stradle the boundary of the buffer and displace the previous two elements.
2390 snprintf(strBuffer, sizeof(strBuffer), "Sample string %zu", num);
2392 err = writer.PutStringF(ProfileTag(TestProfile_1, 1), "Sample string %zu", num);
2393 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
2395 err = writer.Finalize();
2396 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
2398 reader.Init(buffer);
2399 err = reader.Next();
2400 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
2402 err = reader.GetString(valStr, bufsize);
2403 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
2405 NL_TEST_ASSERT(inSuite, strncmp(valStr, strBuffer, bufsize) == 0);
2408 void CheckCHIPTLVSkipCircular(nlTestSuite * inSuite, void * inContext)
2410 const size_t bufsize = 40; // large enough s.t. 2 elements fit, 3rd causes eviction
2411 uint8_t backingStore[bufsize];
2412 char testString[] = "Sample string"; // 13 characters, without the trailing NULL, add 3 bytes for anon tag
2413 // Any pair of reader and writer would work here, either PacketBuffer based or CircularTLV based.
2414 CircularTLVWriter writer;
2415 CircularTLVReader reader;
2416 CHIPCircularTLVBuffer buffer(backingStore, bufsize);
2417 CHIP_ERROR err = CHIP_NO_ERROR;
2419 writer.Init(buffer);
2421 err = writer.PutString(AnonymousTag, testString);
2422 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
2424 err = writer.PutString(AnonymousTag, testString);
2425 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
2427 err = writer.PutString(AnonymousTag, testString); // This event straddles the boundary
2428 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
2430 err = writer.PutString(AnonymousTag, testString); // This one does not.
2431 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
2433 err = writer.Finalize();
2434 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
2436 reader.Init(buffer);
2438 err = reader.Next(); // position the reader at the straddling element
2439 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
2441 err = reader.Skip(); // // Test that the buf ptr is handled correctly within the ReadData() function.
2442 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
2446 * Test Buffer Overflow
2448 void CheckBufferOverflow(nlTestSuite * inSuite, void * inContext)
2450 System::PacketBufferTLVWriter writer;
2451 System::PacketBufferTLVReader reader;
2453 System::PacketBufferHandle buf = System::PacketBufferHandle::New(sizeof(Encoding1), 0);
2454 uint16_t maxDataLen = buf->MaxDataLength();
2455 uint16_t reserve = static_cast<uint16_t>((sizeof(Encoding1) < maxDataLen) ? (maxDataLen - sizeof(Encoding1)) + 2 : 0);
2457 // Repeatedly write and read a TLV encoding to a chain of PacketBuffers. Use progressively larger
2458 // and larger amounts of space in the first buffer to force the encoding/decoding to overlap the
2459 // end of the buffer and the beginning of the next.
2460 for (; reserve < maxDataLen; reserve++)
2462 buf->SetStart(buf->Start() + reserve);
2464 writer.Init(buf.Retain(), /* useChainedBuffers = */ true);
2465 writer.ImplicitProfileId = TestProfile_2;
2467 WriteEncoding1(inSuite, writer);
2469 TestBufferContents(inSuite, buf, Encoding1, sizeof(Encoding1));
2471 reader.Init(buf.Retain(), /* useChainedBuffers = */ true);
2472 reader.ImplicitProfileId = TestProfile_2;
2474 ReadEncoding1(inSuite, reader);
2476 buf = System::PacketBufferHandle::New(System::PacketBuffer::kMaxSizeWithoutReserve, 0);
2481 * Test case to verify the correctness of TLVReader::GetTag()
2483 * TLVReader::GetTag() does not return the correct tag value when the
2484 * the compiler optimization level contains strict aliasing. In the below
2485 * example, the returned tag value would be 0xe, instead of 0xe00000001.
2487 * The issue has been spotted on debug builds.
2491 static const uint8_t sIdentifyResponseBuf[] =
2493 0xD5, 0x00, 0x00, 0x0E, 0x00, 0x01, 0x00, 0x25,
2494 0x00, 0x5A, 0x23, 0x24, 0x01, 0x07, 0x24, 0x02,
2495 0x05, 0x25, 0x03, 0x22, 0x1E, 0x2C, 0x04, 0x10,
2496 0x30, 0x34, 0x41, 0x41, 0x30, 0x31, 0x41, 0x43,
2497 0x32, 0x33, 0x31, 0x34, 0x30, 0x30, 0x4C, 0x50,
2498 0x2C, 0x09, 0x06, 0x31, 0x2E, 0x34, 0x72, 0x63,
2499 0x35, 0x24, 0x0C, 0x01, 0x18,
2503 static const uint32_t kIdentifyResponseLen = 53;
2505 void CheckStrictAliasing(nlTestSuite * inSuite, void * inContext)
2507 const uint32_t kProfile_Id = 0x0000000e;
2508 CHIP_ERROR err = CHIP_NO_ERROR;
2511 reader.Init(sIdentifyResponseBuf, kIdentifyResponseLen);
2512 reader.ImplicitProfileId = kProfile_Id;
2514 err = reader.Next();
2515 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
2517 NL_TEST_ASSERT(inSuite, reader.GetTag() == 0xe00000001);
2521 * Test CHIP TLV Writer Copy Container
2523 void TestCHIPTLVWriterCopyContainer(nlTestSuite * inSuite)
2531 reader.Init(Encoding1, sizeof(Encoding1));
2532 reader.ImplicitProfileId = TestProfile_2;
2534 TestNext<TLVReader>(inSuite, reader);
2536 writer.Init(buf, sizeof(buf));
2537 writer.ImplicitProfileId = TestProfile_2;
2539 CHIP_ERROR err = writer.CopyContainer(reader);
2540 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
2542 uint32_t encodedLen = writer.GetLengthWritten();
2543 NL_TEST_ASSERT(inSuite, encodedLen == sizeof(Encoding1));
2545 int memcmpRes = memcmp(buf, Encoding1, encodedLen);
2546 NL_TEST_ASSERT(inSuite, memcmpRes == 0);
2552 writer.Init(buf, sizeof(buf));
2553 writer.ImplicitProfileId = TestProfile_2;
2555 CHIP_ERROR err = writer.CopyContainer(ProfileTag(TestProfile_1, 1), Encoding1, sizeof(Encoding1));
2556 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
2558 uint32_t encodedLen = writer.GetLengthWritten();
2559 NL_TEST_ASSERT(inSuite, encodedLen == sizeof(Encoding1));
2561 int memcmpRes = memcmp(buf, Encoding1, encodedLen);
2562 NL_TEST_ASSERT(inSuite, memcmpRes == 0);
2567 * Test CHIP TLV Writer Copy Element
2569 void TestCHIPTLVWriterCopyElement(nlTestSuite * inSuite)
2572 uint8_t expectedBuf[2048], testBuf[2048];
2573 uint32_t expectedLen, testLen;
2575 TLVType outerContainerType;
2581 writer.Init(expectedBuf, sizeof(expectedBuf));
2582 writer.ImplicitProfileId = TestProfile_2;
2584 err = writer.StartContainer(AnonymousTag, kTLVType_Structure, outerContainerType);
2585 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
2587 for (int i = 0; i < kRepeatCount; i++)
2589 WriteEncoding1(inSuite, writer);
2592 err = writer.EndContainer(outerContainerType);
2593 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
2595 err = writer.Finalize();
2596 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
2598 expectedLen = writer.GetLengthWritten();
2600 writer.Init(testBuf, sizeof(testBuf));
2601 writer.ImplicitProfileId = TestProfile_2;
2603 err = writer.StartContainer(AnonymousTag, kTLVType_Structure, outerContainerType);
2604 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
2606 for (int i = 0; i < kRepeatCount; i++)
2610 reader.Init(Encoding1, sizeof(Encoding1));
2611 reader.ImplicitProfileId = TestProfile_2;
2613 TestNext<TLVReader>(inSuite, reader);
2615 err = writer.CopyElement(reader);
2616 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
2619 err = writer.EndContainer(outerContainerType);
2620 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
2622 err = writer.Finalize();
2623 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
2625 testLen = writer.GetLengthWritten();
2627 NL_TEST_ASSERT(inSuite, testLen == expectedLen);
2629 int memcmpRes = memcmp(testBuf, expectedBuf, testLen);
2630 NL_TEST_ASSERT(inSuite, memcmpRes == 0);
2633 void PreserveSizeWrite(nlTestSuite * inSuite, TLVWriter & writer, bool preserveSize)
2638 // TLVTagControl::FullyQualified_8Bytes
2639 err = writer.Put(ProfileTag(TestProfile_1, 4000000000ULL), static_cast<int64_t>(40000000000ULL), true);
2640 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
2642 err = writer.Put(ProfileTag(TestProfile_1, 4000000000ULL), static_cast<int16_t>(12345), true);
2643 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
2645 err = writer.Put(ProfileTag(TestProfile_1, 4000000000ULL), static_cast<float>(1.0));
2646 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
2648 err = writer.OpenContainer(ProfileTag(TestProfile_1, 1), kTLVType_Structure, writer2);
2649 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
2654 err = writer2.OpenContainer(ContextTag(0), kTLVType_Array, writer3);
2655 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
2657 err = writer3.Put(AnonymousTag, static_cast<uint8_t>(42), preserveSize);
2658 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
2660 err = writer3.Put(AnonymousTag, static_cast<uint16_t>(42), preserveSize);
2661 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
2663 err = writer3.Put(AnonymousTag, static_cast<uint32_t>(42), preserveSize);
2664 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
2666 err = writer3.Put(AnonymousTag, static_cast<uint64_t>(40000000000ULL), preserveSize);
2667 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
2669 err = writer3.Put(AnonymousTag, static_cast<int8_t>(-17), preserveSize);
2670 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
2672 err = writer3.Put(AnonymousTag, static_cast<int16_t>(-17), preserveSize);
2673 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
2675 err = writer3.Put(AnonymousTag, static_cast<int32_t>(-170000), preserveSize);
2676 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
2678 err = writer3.Put(AnonymousTag, static_cast<int64_t>(-170000), preserveSize);
2679 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
2681 // the below cases are for full coverage of PUTs
2682 err = writer3.Put(AnonymousTag, static_cast<uint64_t>(65535), false);
2683 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
2685 err = writer3.Put(AnonymousTag, static_cast<int64_t>(32767), false);
2686 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
2688 err = writer3.Put(AnonymousTag, static_cast<int64_t>(40000000000ULL), false);
2689 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
2691 err = writer2.CloseContainer(writer3);
2692 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
2695 err = writer.CloseContainer(writer2);
2696 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
2698 err = writer.Finalize();
2699 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
2703 * Test CHIP TLV Writer with Preserve Size
2705 void TestCHIPTLVWriterPreserveSize(nlTestSuite * inSuite)
2710 writer.Init(buf, sizeof(buf));
2711 writer.ImplicitProfileId = TestProfile_2;
2713 PreserveSizeWrite(inSuite, writer, true);
2715 uint32_t encodedLen = writer.GetLengthWritten();
2716 NL_TEST_ASSERT(inSuite, encodedLen == 105);
2720 * Test error handling of CHIP TLV Writer
2722 void TestCHIPTLVWriterErrorHandling(nlTestSuite * inSuite)
2726 TLVWriter writer, writer2, writer3;
2728 writer.Init(buf, sizeof(buf));
2729 writer.ImplicitProfileId = TestProfile_2;
2731 // OpenContainer() for non-container
2732 err = writer.OpenContainer(ProfileTag(TestProfile_1, 1), kTLVType_Boolean, writer2);
2733 NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_WRONG_TLV_TYPE);
2735 // CloseContainer() for non-container
2736 err = writer.CloseContainer(writer2);
2737 NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_INCORRECT_STATE);
2739 // OpenContainer() failure
2740 err = writer.OpenContainer(ProfileTag(TestProfile_1, 1), kTLVType_Structure, writer2);
2741 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
2743 err = writer2.OpenContainer(ProfileTag(TestProfile_1, 1), kTLVType_Structure, writer3);
2744 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
2746 // CloseContainer() failure
2747 err = writer.CloseContainer(writer2);
2748 NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_TLV_CONTAINER_OPEN);
2751 TLVType outerContainerType;
2752 err = writer.StartContainer(ProfileTag(TestProfile_2, 4000000000ULL), kTLVType_Boolean, outerContainerType);
2753 NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_WRONG_TLV_TYPE);
2756 outerContainerType = kTLVType_Boolean;
2757 err = writer.EndContainer(outerContainerType);
2758 NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_INCORRECT_STATE);
2760 // PutPreEncodedContainer()
2762 reader.Init(buf, 2048);
2763 err = writer.PutPreEncodedContainer(ProfileTag(TestProfile_2, 4000000000ULL), kTLVType_Boolean, reader.GetReadPoint(),
2764 reader.GetRemainingLength());
2765 NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_INVALID_ARGUMENT);
2769 * Test CHIP TLV Writer
2771 void CheckCHIPTLVWriter(nlTestSuite * inSuite, void * inContext)
2773 TestCHIPTLVWriterCopyContainer(inSuite);
2775 TestCHIPTLVWriterCopyElement(inSuite);
2777 TestCHIPTLVWriterPreserveSize(inSuite);
2779 TestCHIPTLVWriterErrorHandling(inSuite);
2782 void SkipNonContainer(nlTestSuite * inSuite)
2785 const uint8_t * readpoint1 = nullptr;
2786 const uint8_t * readpoint2 = nullptr;
2788 reader.Init(Encoding1, sizeof(Encoding1));
2789 reader.ImplicitProfileId = TestProfile_2;
2791 TestSkip(inSuite, reader);
2793 readpoint1 = reader.GetReadPoint();
2795 // Skip again, to check the operation is idempotent
2796 TestSkip(inSuite, reader);
2798 readpoint2 = reader.GetReadPoint();
2800 NL_TEST_ASSERT(inSuite, readpoint1 == readpoint2);
2803 void SkipContainer(nlTestSuite * inSuite)
2806 const uint8_t * readpoint1 = nullptr;
2807 const uint8_t * readpoint2 = nullptr;
2809 reader.Init(Encoding1, sizeof(Encoding1));
2810 reader.ImplicitProfileId = TestProfile_2;
2812 TestNext<TLVReader>(inSuite, reader);
2814 TestSkip(inSuite, reader);
2816 readpoint1 = reader.GetReadPoint();
2818 // Skip again, to check the operation is idempotent
2819 TestSkip(inSuite, reader);
2821 readpoint2 = reader.GetReadPoint();
2823 NL_TEST_ASSERT(inSuite, readpoint1 == readpoint2);
2826 void NextContainer(nlTestSuite * inSuite)
2830 reader.Init(Encoding1, sizeof(Encoding1));
2831 reader.ImplicitProfileId = TestProfile_2;
2833 TestNext<TLVReader>(inSuite, reader);
2835 CHIP_ERROR err = reader.Next();
2836 NL_TEST_ASSERT(inSuite, err == CHIP_END_OF_TLV);
2840 * Test CHIP TLV Reader Skip functions
2842 void TestCHIPTLVReaderSkip(nlTestSuite * inSuite)
2844 SkipNonContainer(inSuite);
2846 SkipContainer(inSuite);
2848 NextContainer(inSuite);
2852 * Test CHIP TLV Reader Dup functions
2854 void TestCHIPTLVReaderDup(nlTestSuite * inSuite)
2858 reader.Init(Encoding1, sizeof(Encoding1));
2859 reader.ImplicitProfileId = TestProfile_2;
2861 TestNext<TLVReader>(inSuite, reader);
2866 TestAndOpenContainer(inSuite, reader, kTLVType_Structure, ProfileTag(TestProfile_1, 1), reader2);
2868 TestNext<TLVReader>(inSuite, reader2);
2870 TestGet<TLVReader, bool>(inSuite, reader2, kTLVType_Boolean, ProfileTag(TestProfile_1, 2), true);
2872 TestNext<TLVReader>(inSuite, reader2);
2874 TestGet<TLVReader, bool>(inSuite, reader2, kTLVType_Boolean, ProfileTag(TestProfile_2, 2), false);
2876 TestNext<TLVReader>(inSuite, reader2);
2881 TestAndOpenContainer(inSuite, reader2, kTLVType_Array, ContextTag(0), reader3);
2883 TestNext<TLVReader>(inSuite, reader3);
2885 TestGet<TLVReader, int8_t>(inSuite, reader3, kTLVType_SignedInteger, AnonymousTag, 42);
2886 TestGet<TLVReader, int16_t>(inSuite, reader3, kTLVType_SignedInteger, AnonymousTag, 42);
2887 TestGet<TLVReader, int32_t>(inSuite, reader3, kTLVType_SignedInteger, AnonymousTag, 42);
2888 TestGet<TLVReader, int64_t>(inSuite, reader3, kTLVType_SignedInteger, AnonymousTag, 42);
2889 TestGet<TLVReader, uint32_t>(inSuite, reader3, kTLVType_SignedInteger, AnonymousTag, 42);
2890 TestGet<TLVReader, uint64_t>(inSuite, reader3, kTLVType_SignedInteger, AnonymousTag, 42);
2892 TestNext<TLVReader>(inSuite, reader3);
2894 TestGet<TLVReader, int8_t>(inSuite, reader3, kTLVType_SignedInteger, AnonymousTag, -17);
2895 TestGet<TLVReader, int16_t>(inSuite, reader3, kTLVType_SignedInteger, AnonymousTag, -17);
2896 TestGet<TLVReader, int32_t>(inSuite, reader3, kTLVType_SignedInteger, AnonymousTag, -17);
2897 TestGet<TLVReader, int64_t>(inSuite, reader3, kTLVType_SignedInteger, AnonymousTag, -17);
2899 TestNext<TLVReader>(inSuite, reader3);
2901 TestGet<TLVReader, int32_t>(inSuite, reader3, kTLVType_SignedInteger, AnonymousTag, -170000);
2902 TestGet<TLVReader, int64_t>(inSuite, reader3, kTLVType_SignedInteger, AnonymousTag, -170000);
2904 TestNext<TLVReader>(inSuite, reader3);
2906 TestGet<TLVReader, int64_t>(inSuite, reader3, kTLVType_UnsignedInteger, AnonymousTag, 40000000000ULL);
2907 TestGet<TLVReader, uint64_t>(inSuite, reader3, kTLVType_UnsignedInteger, AnonymousTag, 40000000000ULL);
2909 TestNext<TLVReader>(inSuite, reader3);
2914 TestAndOpenContainer(inSuite, reader3, kTLVType_Structure, AnonymousTag, reader4);
2916 TestEndAndCloseContainer(inSuite, reader3, reader4);
2919 TestNext<TLVReader>(inSuite, reader3);
2924 TestAndOpenContainer(inSuite, reader3, kTLVType_List, AnonymousTag, reader5);
2926 TestNext<TLVReader>(inSuite, reader5);
2928 TestNull(inSuite, reader5, ProfileTag(TestProfile_1, 17));
2930 TestNext<TLVReader>(inSuite, reader5);
2932 TestNull(inSuite, reader5, ProfileTag(TestProfile_2, 900000));
2934 TestNext<TLVReader>(inSuite, reader5);
2936 TestNull(inSuite, reader5, AnonymousTag);
2938 TestNext<TLVReader>(inSuite, reader5);
2941 TLVType outerContainerType;
2943 TestAndEnterContainer<TLVReader>(inSuite, reader5, kTLVType_Structure, ProfileTag(TestProfile_2, 4000000000ULL),
2944 outerContainerType);
2946 TestNext<TLVReader>(inSuite, reader5);
2948 TestDupString(inSuite, reader5, CommonTag(70000), sLargeString);
2950 TestEndAndExitContainer<TLVReader>(inSuite, reader5, outerContainerType);
2953 TestEndAndCloseContainer(inSuite, reader3, reader5);
2956 TestEndAndCloseContainer(inSuite, reader2, reader3);
2959 TestNext<TLVReader>(inSuite, reader2);
2961 TestDupBytes(inSuite, reader2, ProfileTag(TestProfile_1, 5), reinterpret_cast<const uint8_t *>("This is a test"), 14);
2963 TestNext<TLVReader>(inSuite, reader2);
2965 TestGet<TLVReader, double>(inSuite, reader2, kTLVType_FloatingPointNumber, ProfileTag(TestProfile_2, 65535),
2966 static_cast<float>(17.9));
2968 TestNext<TLVReader>(inSuite, reader2);
2970 TestGet<TLVReader, double>(inSuite, reader2, kTLVType_FloatingPointNumber, ProfileTag(TestProfile_2, 65536), 17.9);
2972 TestEndAndCloseContainer(inSuite, reader, reader2);
2975 TestEnd<TLVReader>(inSuite, reader);
2978 * Test error handling of CHIP TLV Reader
2980 void TestCHIPTLVReaderErrorHandling(nlTestSuite * inSuite)
2986 reader.Init(buf, sizeof(buf));
2987 reader.ImplicitProfileId = TestProfile_2;
2991 err = reader.Get(val);
2992 NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_WRONG_TLV_TYPE);
2996 err = reader.Get(numD);
2997 NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_WRONG_TLV_TYPE);
3001 err = reader.Get(num);
3002 NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_WRONG_TLV_TYPE);
3006 err = reader.GetBytes(bBuf, sizeof(bBuf));
3007 NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_WRONG_TLV_TYPE);
3011 err = reader.GetString(sBuf, sizeof(sBuf));
3012 NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_WRONG_TLV_TYPE);
3016 err = reader.OpenContainer(reader2);
3017 NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_INCORRECT_STATE);
3020 err = reader.CloseContainer(reader2);
3021 NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_INCORRECT_STATE);
3024 TLVType outerContainerType = kTLVType_Boolean;
3025 err = reader.EnterContainer(outerContainerType);
3026 NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_INCORRECT_STATE);
3029 char * str = static_cast<char *>(chip::Platform::MemoryAlloc(16));
3030 err = reader.DupString(str);
3031 NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_WRONG_TLV_TYPE);
3032 chip::Platform::MemoryFree(str);
3035 const uint8_t * data = static_cast<uint8_t *>(chip::Platform::MemoryAlloc(16));
3036 err = reader.GetDataPtr(data);
3037 NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_WRONG_TLV_TYPE);
3038 chip::Platform::MemoryFree(const_cast<uint8_t *>(data));
3041 * Test CHIP TLV Reader in a use case
3043 void TestCHIPTLVReaderInPractice(nlTestSuite * inSuite)
3049 writer.Init(buf, sizeof(buf));
3050 writer.ImplicitProfileId = TestProfile_2;
3052 PreserveSizeWrite(inSuite, writer, true);
3054 reader.Init(buf, sizeof(buf));
3056 TestNext<TLVReader>(inSuite, reader);
3058 TestGet<TLVReader, int64_t>(inSuite, reader, kTLVType_SignedInteger, ProfileTag(TestProfile_1, 4000000000ULL),
3059 static_cast<int64_t>(40000000000ULL));
3061 TestNext<TLVReader>(inSuite, reader);
3063 TestGet<TLVReader, int64_t>(inSuite, reader, kTLVType_SignedInteger, ProfileTag(TestProfile_1, 4000000000ULL),
3064 static_cast<int16_t>(12345));
3066 TestNext<TLVReader>(inSuite, reader);
3068 TestGet<TLVReader, double>(inSuite, reader, kTLVType_FloatingPointNumber, ProfileTag(TestProfile_1, 4000000000ULL),
3069 static_cast<float>(1.0));
3072 void TestCHIPTLVReader_NextOverContainer_ProcessElement(nlTestSuite * inSuite, TLVReader & reader, void * context)
3074 CHIP_ERROR err, nextRes1, nextRes2;
3075 TLVType outerContainerType;
3077 // If the current element is a container...
3078 if (TLVTypeIsContainer(reader.GetType()))
3080 // Make two copies of the reader
3081 TLVReader readerClone1 = reader;
3082 TLVReader readerClone2 = reader;
3084 // Manually advance one of the readers to the element immediately after the container (if any).
3085 err = readerClone1.EnterContainer(outerContainerType);
3086 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
3087 ForEachElement(inSuite, readerClone1, nullptr, nullptr);
3088 err = readerClone1.ExitContainer(outerContainerType);
3089 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
3090 nextRes1 = readerClone1.Next();
3091 NL_TEST_ASSERT(inSuite, nextRes1 == CHIP_NO_ERROR || nextRes1 == CHIP_END_OF_TLV);
3093 // For the other reader, skip over the entire container using the Next() method.
3094 nextRes2 = readerClone2.Next();
3095 NL_TEST_ASSERT(inSuite, nextRes2 == CHIP_NO_ERROR || nextRes2 == CHIP_END_OF_TLV);
3097 // Verify the two readers end up in the same state/position.
3098 NL_TEST_ASSERT(inSuite, nextRes1 == nextRes2);
3099 NL_TEST_ASSERT(inSuite, readerClone1.GetType() == readerClone2.GetType());
3100 NL_TEST_ASSERT(inSuite, readerClone1.GetReadPoint() == readerClone2.GetReadPoint());
3105 * Test using CHIP TLV Reader Next() method to skip over containers.
3107 void TestCHIPTLVReader_NextOverContainer(nlTestSuite * inSuite)
3111 reader.Init(Encoding1, sizeof(Encoding1));
3112 reader.ImplicitProfileId = TestProfile_2;
3114 ForEachElement(inSuite, reader, nullptr, TestCHIPTLVReader_NextOverContainer_ProcessElement);
3117 void TestCHIPTLVReader_SkipOverContainer_ProcessElement(nlTestSuite * inSuite, TLVReader & reader, void * context)
3120 TLVType outerContainerType;
3122 // If the current element is a container...
3123 if (TLVTypeIsContainer(reader.GetType()))
3125 // Make two copies of the reader
3126 TLVReader readerClone1 = reader;
3127 TLVReader readerClone2 = reader;
3129 // Manually advance one of the readers to immediately after the container.
3130 err = readerClone1.EnterContainer(outerContainerType);
3131 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
3132 ForEachElement(inSuite, readerClone1, nullptr, nullptr);
3133 err = readerClone1.ExitContainer(outerContainerType);
3134 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
3136 // For the other reader, skip over the entire container using the Skip() method.
3137 err = readerClone2.Skip();
3138 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
3140 // Verify the two readers end up in the same state/position.
3141 NL_TEST_ASSERT(inSuite, readerClone1.GetType() == readerClone2.GetType());
3142 NL_TEST_ASSERT(inSuite, readerClone1.GetReadPoint() == readerClone2.GetReadPoint());
3147 * Test using CHIP TLV Reader Skip() method to skip over containers.
3149 void TestCHIPTLVReader_SkipOverContainer(nlTestSuite * inSuite)
3153 reader.Init(Encoding1, sizeof(Encoding1));
3154 reader.ImplicitProfileId = TestProfile_2;
3156 ForEachElement(inSuite, reader, nullptr, TestCHIPTLVReader_SkipOverContainer_ProcessElement);
3160 * Test CHIP TLV Reader
3162 void CheckCHIPTLVReader(nlTestSuite * inSuite, void * inContext)
3164 TestCHIPTLVReaderSkip(inSuite);
3166 TestCHIPTLVReaderDup(inSuite);
3168 TestCHIPTLVReaderErrorHandling(inSuite);
3170 TestCHIPTLVReaderInPractice(inSuite);
3172 TestCHIPTLVReader_NextOverContainer(inSuite);
3174 TestCHIPTLVReader_SkipOverContainer(inSuite);
3178 * Test CHIP TLV Items
3180 static void TestItems(nlTestSuite * inSuite, void * inContext)
3182 CHIP_ERROR err = CHIP_NO_ERROR;
3184 uint8_t sBuffer[256];
3187 writer.Init(sBuffer, sizeof(sBuffer));
3190 err = writer.OpenContainer(AnonymousTag, kTLVType_Array, writer2);
3191 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
3194 err = writer2.PutBoolean(AnonymousTag, true);
3195 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
3197 err = writer2.Put(AnonymousTag, static_cast<int8_t>(-1));
3198 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
3200 err = writer2.Put(AnonymousTag, static_cast<int16_t>(-2));
3201 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
3203 err = writer2.Put(AnonymousTag, static_cast<int32_t>(-3));
3204 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
3206 err = writer2.Put(AnonymousTag, static_cast<int64_t>(-4));
3207 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
3209 err = writer2.Put(AnonymousTag, static_cast<float>(-5.5));
3210 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
3212 err = writer2.Put(AnonymousTag, static_cast<double>(-3.14159265358979323846));
3213 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
3216 err = writer.CloseContainer(writer2);
3217 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
3219 err = writer.OpenContainer(AnonymousTag, kTLVType_Array, writer2);
3220 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
3223 err = writer2.PutBoolean(AnonymousTag, false);
3224 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
3226 err = writer2.Put(AnonymousTag, static_cast<int8_t>(1));
3227 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
3229 err = writer2.Put(AnonymousTag, static_cast<int16_t>(2));
3230 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
3232 err = writer2.Put(AnonymousTag, static_cast<int32_t>(3));
3233 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
3235 err = writer2.Put(AnonymousTag, static_cast<int64_t>(4));
3236 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
3238 err = writer2.Put(AnonymousTag, static_cast<uint8_t>(5));
3239 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
3241 err = writer2.Put(AnonymousTag, static_cast<uint16_t>(6));
3242 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
3244 err = writer2.Put(AnonymousTag, static_cast<uint32_t>(7));
3245 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
3247 err = writer2.Put(AnonymousTag, static_cast<uint64_t>(8));
3248 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
3250 err = writer2.Put(AnonymousTag, static_cast<float>(9.9));
3251 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
3253 err = writer2.Put(AnonymousTag, static_cast<double>(3.14159265358979323846));
3254 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
3257 err = writer.CloseContainer(writer2);
3258 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
3260 err = writer.Finalize();
3261 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
3265 * Test CHIP TLV Containers
3267 static void TestContainers(nlTestSuite * inSuite, void * inContext)
3269 CHIP_ERROR err = CHIP_NO_ERROR;
3272 uint8_t sBuffer[256];
3273 writer.Init(sBuffer, sizeof(sBuffer));
3276 err = writer.OpenContainer(AnonymousTag, kTLVType_Array, writer2);
3277 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
3279 TLVType type = writer2.GetContainerType();
3280 NL_TEST_ASSERT(inSuite, type == kTLVType_Array);
3282 err = writer.CloseContainer(writer2);
3283 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
3285 err = writer.OpenContainer(AnonymousTag, kTLVType_Structure, writer2);
3286 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
3288 type = writer2.GetContainerType();
3289 NL_TEST_ASSERT(inSuite, type == kTLVType_Structure);
3291 err = writer.CloseContainer(writer2);
3292 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
3294 err = writer.Finalize();
3295 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
3299 * Test CHIP TLV Basics
3301 static void CheckCHIPTLVBasics(nlTestSuite * inSuite, void * inContext)
3303 TestItems(inSuite, inContext);
3304 TestContainers(inSuite, inContext);
3308 * Test CHIP TLV Updater
3310 static void CheckCHIPUpdater(nlTestSuite * inSuite, void * inContext)
3312 WriteAppendReadTest0(inSuite);
3314 WriteAppendReadTest1(inSuite);
3316 WriteFindAppendReadTest(inSuite, false); // Find an element
3318 WriteFindAppendReadTest(inSuite, true); // Find a container
3320 AppendReadTest(inSuite);
3322 WriteDeleteReadTest(inSuite);
3326 * Test TLV CloseContainer symbol reservations
3329 class OptimisticTLVWriter : public TLVWriter
3332 void Init(uint8_t * buf, uint32_t maxLen);
3335 void OptimisticTLVWriter::Init(uint8_t * buf, uint32_t maxLen)
3337 TLVWriter::Init(buf, maxLen);
3338 SetCloseContainerReserved(false);
3341 static void CheckCloseContainerReserve(nlTestSuite * inSuite, void * inContext)
3343 // We are writing the structure looking like:
3345 // [{TestProfile_1:2: true}]
3347 // the above should consume 11 bytes in the TLV encoding. The
3348 // chosen buffer is too small for that, this test verifies that we
3349 // fail in the right places in the code. With the standard
3350 // TLVWriter, we now make provisions to reserve the space for the
3351 // CloseContainer tag in the OpenContainer call. As a result, we
3352 // expect to error out when we attempt to write out the value for
3353 // the TestProfile_1:2 tag. In contrast, the
3354 // `OptimisticTLVWriter` implements the earlier TLVWriter behavior
3355 // and fails out in the last CloseContainer call. The error
3356 // caught there is different because we run up against the mMaxLen
3357 // rather than mRemainingLen check.
3361 CHIP_ERROR err = CHIP_NO_ERROR;
3363 OptimisticTLVWriter writer2;
3364 TLVWriter innerWriter1, innerWriter2;
3365 TLVType container1, container2;
3367 writer1.Init(buf, sizeof(buf));
3369 err = writer1.OpenContainer(AnonymousTag, kTLVType_Array, innerWriter1);
3370 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
3372 err = innerWriter1.OpenContainer(AnonymousTag, kTLVType_Structure, innerWriter2);
3373 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
3375 err = innerWriter2.PutBoolean(ProfileTag(TestProfile_1, 2), true);
3376 NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_BUFFER_TOO_SMALL);
3378 err = innerWriter1.CloseContainer(innerWriter2);
3379 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
3381 err = writer1.CloseContainer(innerWriter1);
3382 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
3384 writer2.Init(buf, sizeof(buf));
3386 err = writer2.OpenContainer(AnonymousTag, kTLVType_Array, innerWriter1);
3387 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
3389 err = innerWriter1.OpenContainer(AnonymousTag, kTLVType_Structure, innerWriter2);
3390 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
3392 err = innerWriter2.PutBoolean(ProfileTag(TestProfile_1, 2), true);
3393 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
3395 err = innerWriter1.CloseContainer(innerWriter2);
3396 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
3398 err = writer2.CloseContainer(innerWriter1);
3399 NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_BUFFER_TOO_SMALL);
3401 // test the same scheme works on the Start/End container
3403 writer1.Init(buf, sizeof(buf));
3405 err = writer1.StartContainer(AnonymousTag, kTLVType_Array, container1);
3406 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
3408 err = writer1.StartContainer(AnonymousTag, kTLVType_Structure, container2);
3409 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
3411 err = writer1.PutBoolean(ProfileTag(TestProfile_1, 2), true);
3412 NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_BUFFER_TOO_SMALL);
3414 err = writer1.EndContainer(container2);
3415 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
3417 err = writer1.EndContainer(container1);
3418 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
3420 writer2.Init(buf, sizeof(buf));
3422 err = writer2.StartContainer(AnonymousTag, kTLVType_Array, container1);
3423 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
3425 err = writer2.StartContainer(AnonymousTag, kTLVType_Structure, container2);
3426 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
3428 err = writer2.PutBoolean(ProfileTag(TestProfile_1, 2), true);
3429 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
3431 err = writer2.EndContainer(container2);
3432 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
3434 err = writer2.EndContainer(container1);
3435 NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_BUFFER_TOO_SMALL);
3437 // Test that the reservations work for the empty containers
3439 writer1.Init(buf1, sizeof(buf1));
3440 err = writer1.OpenContainer(ProfileTag(TestProfile_1, 2), kTLVType_Structure, innerWriter1);
3441 NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_BUFFER_TOO_SMALL);
3443 err = writer1.CloseContainer(innerWriter1);
3444 NL_TEST_ASSERT(inSuite, err != CHIP_NO_ERROR);
3446 writer2.Init(buf1, sizeof(buf1));
3447 err = writer2.OpenContainer(ProfileTag(TestProfile_1, 2), kTLVType_Structure, innerWriter1);
3448 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
3450 err = writer2.CloseContainer(innerWriter1);
3451 NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_BUFFER_TOO_SMALL);
3453 writer1.Init(buf1, sizeof(buf1));
3455 err = writer1.StartContainer(ProfileTag(TestProfile_1, 2), kTLVType_Structure, container1);
3456 NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_BUFFER_TOO_SMALL);
3458 err = writer1.EndContainer(container1);
3459 NL_TEST_ASSERT(inSuite, err != CHIP_NO_ERROR);
3461 writer2.Init(buf1, sizeof(buf1));
3463 err = writer2.StartContainer(ProfileTag(TestProfile_1, 2), kTLVType_Structure, container1);
3464 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
3466 err = writer2.EndContainer(container1);
3467 NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_BUFFER_TOO_SMALL);
3469 // Test that the reservations work if the writer has a maxLen of 0.
3471 writer1.Init(buf1, 0);
3473 err = writer1.OpenContainer(ProfileTag(TestProfile_1, 2), kTLVType_Structure, innerWriter1);
3474 NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_BUFFER_TOO_SMALL);
3476 err = writer1.StartContainer(AnonymousTag, kTLVType_Array, container1);
3477 NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_BUFFER_TOO_SMALL);
3479 // Test again all cases from 0 to the length of buf1
3481 for (uint32_t maxLen = 0; maxLen <= sizeof(buf); maxLen++)
3483 // Open/CloseContainer
3485 writer1.Init(buf, maxLen);
3487 err = writer1.OpenContainer(AnonymousTag, kTLVType_Array, innerWriter1);
3489 if (err == CHIP_NO_ERROR)
3490 err = innerWriter1.OpenContainer(AnonymousTag, kTLVType_Structure, innerWriter2);
3492 if (err == CHIP_NO_ERROR)
3493 err = innerWriter2.PutBoolean(ProfileTag(TestProfile_1, 2), true);
3495 if (err == CHIP_NO_ERROR)
3496 err = innerWriter1.CloseContainer(innerWriter2);
3498 if (err == CHIP_NO_ERROR)
3499 err = writer1.CloseContainer(innerWriter1);
3501 NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_BUFFER_TOO_SMALL);
3503 // Start/EndContainer
3505 writer1.Init(buf, maxLen);
3507 if (err == CHIP_NO_ERROR)
3508 err = writer1.StartContainer(AnonymousTag, kTLVType_Array, container1);
3510 if (err == CHIP_NO_ERROR)
3511 err = writer1.StartContainer(AnonymousTag, kTLVType_Structure, container2);
3513 if (err == CHIP_NO_ERROR)
3514 err = writer1.PutBoolean(ProfileTag(TestProfile_1, 2), true);
3516 if (err == CHIP_NO_ERROR)
3517 err = writer1.EndContainer(container2);
3519 if (err == CHIP_NO_ERROR)
3520 err = writer1.EndContainer(container1);
3522 NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_BUFFER_TOO_SMALL);
3526 static CHIP_ERROR ReadFuzzedEncoding1(nlTestSuite * inSuite, TLVReader & reader)
3528 CHIP_ERROR err = CHIP_NO_ERROR;
3530 #define FUZZ_CHECK_VAL(TYPE, VAL) \
3534 ReturnErrorOnFailure(reader.Get(val)); \
3535 VerifyOrReturnError(val == (VAL), CHIP_ERROR_INVALID_ARGUMENT); \
3538 #define FUZZ_CHECK_STRING(VAL) \
3541 char buf[sizeof(VAL)]; \
3542 VerifyOrReturnError(reader.GetLength() == strlen(VAL), CHIP_ERROR_INVALID_ADDRESS); \
3543 ReturnErrorOnFailure(reader.GetString(buf, sizeof(buf))); \
3544 VerifyOrReturnError(strcmp(buf, (VAL)) == 0, CHIP_ERROR_INVALID_ADDRESS); \
3547 ReturnErrorOnFailure(reader.Next(kTLVType_Structure, ProfileTag(TestProfile_1, 1)));
3550 TLVType outerContainer1Type;
3552 ReturnErrorOnFailure(reader.EnterContainer(outerContainer1Type));
3553 ReturnErrorOnFailure(reader.Next(kTLVType_Boolean, ProfileTag(TestProfile_1, 2)));
3555 FUZZ_CHECK_VAL(bool, true);
3557 ReturnErrorOnFailure(reader.Next(kTLVType_Boolean, ProfileTag(TestProfile_2, 2)));
3559 FUZZ_CHECK_VAL(bool, false);
3561 ReturnErrorOnFailure(reader.Next(kTLVType_Array, ContextTag(0)));
3564 TLVType outerContainer2Type;
3566 ReturnErrorOnFailure(reader.EnterContainer(outerContainer2Type));
3567 ReturnErrorOnFailure(reader.Next(kTLVType_SignedInteger, AnonymousTag));
3569 FUZZ_CHECK_VAL(int8_t, 42);
3570 FUZZ_CHECK_VAL(int16_t, 42);
3571 FUZZ_CHECK_VAL(int32_t, 42);
3572 FUZZ_CHECK_VAL(int64_t, 42);
3573 FUZZ_CHECK_VAL(uint8_t, 42);
3574 FUZZ_CHECK_VAL(uint16_t, 42);
3575 FUZZ_CHECK_VAL(uint32_t, 42);
3576 FUZZ_CHECK_VAL(uint64_t, 42);
3578 ReturnErrorOnFailure(reader.Next(kTLVType_SignedInteger, AnonymousTag));
3580 FUZZ_CHECK_VAL(int8_t, -17);
3581 FUZZ_CHECK_VAL(int16_t, -17);
3582 FUZZ_CHECK_VAL(int32_t, -17);
3583 FUZZ_CHECK_VAL(int64_t, -17);
3585 ReturnErrorOnFailure(reader.Next(kTLVType_SignedInteger, AnonymousTag));
3587 FUZZ_CHECK_VAL(int32_t, -170000);
3588 FUZZ_CHECK_VAL(int64_t, -170000);
3590 ReturnErrorOnFailure(reader.Next(kTLVType_UnsignedInteger, AnonymousTag));
3592 FUZZ_CHECK_VAL(int64_t, 40000000000ULL);
3593 FUZZ_CHECK_VAL(uint64_t, 40000000000ULL);
3595 ReturnErrorOnFailure(reader.Next(kTLVType_Structure, AnonymousTag));
3598 TLVType outerContainer3Type;
3600 ReturnErrorOnFailure(reader.EnterContainer(outerContainer3Type));
3601 ReturnErrorOnFailure(reader.ExitContainer(outerContainer3Type));
3604 ReturnErrorOnFailure(reader.Next(kTLVType_List, AnonymousTag));
3607 TLVType outerContainer3Type;
3609 ReturnErrorOnFailure(reader.EnterContainer(outerContainer3Type));
3610 ReturnErrorOnFailure(reader.Next(kTLVType_Null, ProfileTag(TestProfile_1, 17)));
3611 ReturnErrorOnFailure(reader.Next(kTLVType_Null, ProfileTag(TestProfile_2, 900000)));
3612 ReturnErrorOnFailure(reader.Next(kTLVType_Null, AnonymousTag));
3613 ReturnErrorOnFailure(reader.Next(kTLVType_Structure, ProfileTag(TestProfile_2, 4000000000ULL)));
3616 TLVType outerContainer4Type;
3618 ReturnErrorOnFailure(reader.EnterContainer(outerContainer4Type));
3619 ReturnErrorOnFailure(reader.Next(kTLVType_UTF8String, CommonTag(70000)));
3621 FUZZ_CHECK_STRING(sLargeString);
3623 ReturnErrorOnFailure(reader.ExitContainer(outerContainer4Type));
3626 ReturnErrorOnFailure(reader.ExitContainer(outerContainer3Type));
3629 ReturnErrorOnFailure(reader.ExitContainer(outerContainer2Type));
3632 ReturnErrorOnFailure(reader.Next(kTLVType_UTF8String, ProfileTag(TestProfile_1, 5)));
3634 FUZZ_CHECK_STRING("This is a test");
3636 ReturnErrorOnFailure(reader.Next(kTLVType_FloatingPointNumber, ProfileTag(TestProfile_2, 65535)));
3638 FUZZ_CHECK_VAL(double, (float) 17.9);
3640 ReturnErrorOnFailure(reader.Next(kTLVType_FloatingPointNumber, ProfileTag(TestProfile_2, 65536)));
3642 FUZZ_CHECK_VAL(double, (double) 17.9);
3644 ReturnErrorOnFailure(reader.ExitContainer(outerContainer1Type));
3647 err = reader.Next();
3648 if (err == CHIP_END_OF_TLV)
3649 err = CHIP_NO_ERROR;
3651 return CHIP_NO_ERROR;
3654 static time_t sFuzzTestDurationSecs = 5;
3655 static uint8_t sFixedFuzzMask = 0;
3657 static void TLVReaderFuzzTest(nlTestSuite * inSuite, void * inContext)
3659 time_t now, endTime;
3660 uint8_t fuzzedData[sizeof(Encoding1)];
3663 static uint8_t sFixedFuzzVals[] =
3668 0x20, // 1-byte signed integer with context tag
3669 0x21, // 2-byte signed integer with context tag
3670 0x22, // 4-byte signed integer with context tag
3671 0x23, // 8-byte signed integer with context tag
3672 0x24, // 1-byte unsigned integer with context tag
3673 0x25, // 1-byte unsigned integer with context tag
3674 0x26, // 1-byte unsigned integer with context tag
3675 0x27, // 1-byte unsigned integer with context tag
3676 0x28, // Boolean false with context tag
3677 0x29, // Boolean true with context tag
3678 0x27, // UTF-8 string with 1-byte length and context tag
3679 0x30, // Byte string with 1-byte length and context tag
3680 0x35, // Structure with context tag
3681 0x36, // Array with context tag
3682 0x18, // End of container
3686 memcpy(fuzzedData, Encoding1, sizeof(fuzzedData));
3689 endTime = now + sFuzzTestDurationSecs + 1;
3691 srand(static_cast<unsigned int>(now));
3696 for (size_t i = 0; i < sizeof(fuzzedData); i++)
3698 uint8_t origVal = fuzzedData[i];
3700 if (m < sizeof(sFixedFuzzVals))
3702 if (origVal == sFixedFuzzVals[m])
3705 fuzzedData[i] = sFixedFuzzVals[m];
3710 uint8_t fuzzMask = sFixedFuzzMask;
3711 while (fuzzMask == 0)
3712 fuzzMask = GetRandU8();
3714 fuzzedData[i] ^= fuzzMask;
3718 reader.Init(fuzzedData, sizeof(fuzzedData));
3719 reader.ImplicitProfileId = TestProfile_2;
3721 CHIP_ERROR readRes = ReadFuzzedEncoding1(inSuite, reader);
3722 NL_TEST_ASSERT(inSuite, readRes != CHIP_NO_ERROR);
3724 if (readRes == CHIP_NO_ERROR)
3726 printf("Unexpected success of fuzz test: offset %u, original value 0x%02X, mutated value 0x%02X\n",
3727 static_cast<unsigned>(i), static_cast<unsigned>(origVal), static_cast<unsigned>(fuzzedData[i]));
3735 fuzzedData[i] = origVal;
3738 if (m < sizeof(sFixedFuzzVals))
3749 * Test Suite that lists all the test functions.
3752 static const nlTest sTests[] =
3754 NL_TEST_DEF("Simple Write Read Test", CheckSimpleWriteRead),
3755 NL_TEST_DEF("Inet Buffer Test", CheckPacketBuffer),
3756 NL_TEST_DEF("Buffer Overflow Test", CheckBufferOverflow),
3757 NL_TEST_DEF("Pretty Print Test", CheckPrettyPrinter),
3758 NL_TEST_DEF("Data Macro Test", CheckDataMacro),
3759 NL_TEST_DEF("Strict Aliasing Test", CheckStrictAliasing),
3760 NL_TEST_DEF("CHIP TLV Basics", CheckCHIPTLVBasics),
3761 NL_TEST_DEF("CHIP TLV Writer", CheckCHIPTLVWriter),
3762 NL_TEST_DEF("CHIP TLV Reader", CheckCHIPTLVReader),
3763 NL_TEST_DEF("CHIP TLV Utilities", CheckCHIPTLVUtilities),
3764 NL_TEST_DEF("CHIP TLV Updater", CheckCHIPUpdater),
3765 NL_TEST_DEF("CHIP TLV Empty Find", CheckCHIPTLVEmptyFind),
3766 NL_TEST_DEF("CHIP Circular TLV buffer, simple", CheckCircularTLVBufferSimple),
3767 NL_TEST_DEF("CHIP Circular TLV buffer, mid-buffer start", CheckCircularTLVBufferStartMidway),
3768 NL_TEST_DEF("CHIP Circular TLV buffer, straddle", CheckCircularTLVBufferEvictStraddlingEvent),
3769 NL_TEST_DEF("CHIP Circular TLV buffer, edge", CheckCircularTLVBufferEdge),
3770 NL_TEST_DEF("CHIP TLV Printf", CheckCHIPTLVPutStringF),
3771 NL_TEST_DEF("CHIP TLV Printf, Circular TLV buf", CheckCHIPTLVPutStringFCircular),
3772 NL_TEST_DEF("CHIP TLV Skip non-contiguous", CheckCHIPTLVSkipCircular),
3773 NL_TEST_DEF("CHIP TLV Check reserve", CheckCloseContainerReserve),
3774 NL_TEST_DEF("CHIP TLV Reader Fuzz Test", TLVReaderFuzzTest),
3781 * Set up the test suite.
3783 int TestCHIPTLV_Setup(void * inContext)
3785 CHIP_ERROR error = chip::Platform::MemoryInit();
3786 if (error != CHIP_NO_ERROR)
3792 * Tear down the test suite.
3794 int TestCHIPTLV_Teardown(void * inContext)
3796 chip::Platform::MemoryShutdown();
3800 int TestCHIPTLV(void)
3803 nlTestSuite theSuite =
3808 TestCHIPTLV_Teardown
3811 TestTLVContext context;
3813 context.mSuite = &theSuite;
3815 // Run test suit against one context
3816 nlTestRunner(&theSuite, &context);
3818 return (nlTestRunnerStats(&theSuite));
3821 CHIP_REGISTER_TEST_SUITE(TestCHIPTLV)