Skip to content

Commit 3786192

Browse files
yufengwangcatcarmelveilleux
authored andcommitted
Support for encoding Field IDs with an MC source (project-chip#32276)
* Support for encoding Field IDs with an MC source * Update src/lib/support/jsontlv/JsonToTlv.h Co-authored-by: Tennessee Carmel-Veilleux <tennessee.carmelveilleux@gmail.com> * Address review comments * Fix linter * Fix linter * restyle --------- Co-authored-by: Tennessee Carmel-Veilleux <tennessee.carmelveilleux@gmail.com>
1 parent 982d9bf commit 3786192

File tree

5 files changed

+167
-34
lines changed

5 files changed

+167
-34
lines changed

src/lib/support/jsontlv/JsonToTlv.cpp

+42-10
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
*/
1717

1818
#include <algorithm>
19+
#include <errno.h>
1920
#include <json/json.h>
2021
#include <lib/support/Base64.h>
2122
#include <lib/support/SafeInt.h>
@@ -179,26 +180,34 @@ bool CompareByTag(const ElementContext & a, const ElementContext & b)
179180
return IsContextTag(a.tag);
180181
}
181182

182-
CHIP_ERROR InternalConvertTlvTag(const uint64_t tagNumber, TLV::Tag & tag, const uint32_t profileId = kTemporaryImplicitProfileId)
183+
// The profileId parameter is used when encoding a tag for a TLV element to specify the profile that the tag belongs to.
184+
// If the vendor ID is zero but the tag ID does not fit within an 8-bit value, the function uses Implicit Profile Tag.
185+
// Here, the kTemporaryImplicitProfileId serves as a default value for cases where no explicit profile ID is provided by
186+
// the caller. This allows for the encoding of tags that are not vendor-specific or context-specific but are instead
187+
// associated with a temporary implicit profile ID (0xFF01).
188+
CHIP_ERROR InternalConvertTlvTag(uint32_t tagNumber, TLV::Tag & tag, const uint32_t profileId = kTemporaryImplicitProfileId)
183189
{
184-
if (tagNumber <= UINT8_MAX)
190+
uint16_t vendor_id = static_cast<uint16_t>(tagNumber >> 16);
191+
uint16_t tag_id = static_cast<uint16_t>(tagNumber & 0xFFFF);
192+
193+
if (vendor_id != 0)
185194
{
186-
tag = TLV::ContextTag(static_cast<uint8_t>(tagNumber));
195+
tag = TLV::ProfileTag(vendor_id, /*profileNum=*/0, tag_id);
187196
}
188-
else if (tagNumber <= UINT32_MAX)
197+
else if (tag_id <= UINT8_MAX)
189198
{
190-
tag = TLV::ProfileTag(profileId, static_cast<uint32_t>(tagNumber));
199+
tag = TLV::ContextTag(static_cast<uint8_t>(tagNumber));
191200
}
192201
else
193202
{
194-
return CHIP_ERROR_INVALID_ARGUMENT;
203+
tag = TLV::ProfileTag(profileId, tagNumber);
195204
}
196205
return CHIP_NO_ERROR;
197206
}
198207

199208
CHIP_ERROR ParseJsonName(const std::string name, ElementContext & elementCtx, uint32_t implicitProfileId)
200209
{
201-
uint64_t tagNumber = 0;
210+
uint32_t tagNumber = 0;
202211
const char * elementType = nullptr;
203212
std::vector<std::string> nameFields = SplitIntoFieldsBySeparator(name, ':');
204213
TLV::Tag tag = TLV::AnonymousTag();
@@ -208,13 +217,27 @@ CHIP_ERROR ParseJsonName(const std::string name, ElementContext & elementCtx, ui
208217
if (nameFields.size() == 2)
209218
{
210219
VerifyOrReturnError(IsUnsignedInteger(nameFields[0]), CHIP_ERROR_INVALID_ARGUMENT);
211-
tagNumber = std::strtoull(nameFields[0].c_str(), nullptr, 10);
220+
221+
char * endPtr;
222+
errno = 0;
223+
unsigned long result = strtoul(nameFields[0].c_str(), &endPtr, 10);
224+
VerifyOrReturnError(nameFields[0].c_str() != endPtr, CHIP_ERROR_INVALID_ARGUMENT);
225+
VerifyOrReturnError((errno != ERANGE && result <= UINT32_MAX), CHIP_ERROR_INVALID_ARGUMENT);
226+
227+
tagNumber = static_cast<uint32_t>(result);
212228
elementType = nameFields[1].c_str();
213229
}
214230
else if (nameFields.size() == 3)
215231
{
216232
VerifyOrReturnError(IsUnsignedInteger(nameFields[1]), CHIP_ERROR_INVALID_ARGUMENT);
217-
tagNumber = std::strtoull(nameFields[1].c_str(), nullptr, 10);
233+
234+
char * endPtr;
235+
errno = 0;
236+
unsigned long result = strtoul(nameFields[1].c_str(), &endPtr, 10);
237+
VerifyOrReturnError(nameFields[1].c_str() != endPtr, CHIP_ERROR_INVALID_ARGUMENT);
238+
VerifyOrReturnError((errno != ERANGE && result <= UINT32_MAX), CHIP_ERROR_INVALID_ARGUMENT);
239+
240+
tagNumber = static_cast<uint32_t>(result);
218241
elementType = nameFields[2].c_str();
219242
}
220243
else
@@ -459,10 +482,19 @@ CHIP_ERROR JsonToTlv(const std::string & jsonString, TLV::TLVWriter & writer)
459482

460483
ElementContext elementCtx;
461484
elementCtx.type = { TLV::kTLVType_Structure, false };
485+
486+
// Use kTemporaryImplicitProfileId as the default value for cases where no explicit implicit profile ID is provided by
487+
// the caller. This allows for the encoding of tags that are not vendor-specific or context-specific but are instead
488+
// associated with a temporary implicit profile ID (0xFF01).
489+
if (writer.ImplicitProfileId == TLV::kProfileIdNotSpecified)
490+
{
491+
writer.ImplicitProfileId = kTemporaryImplicitProfileId;
492+
}
493+
462494
return EncodeTlvElement(json, writer, elementCtx);
463495
}
464496

465-
CHIP_ERROR ConvertTlvTag(const uint64_t tagNumber, TLV::Tag & tag)
497+
CHIP_ERROR ConvertTlvTag(uint32_t tagNumber, TLV::Tag & tag)
466498
{
467499
return InternalConvertTlvTag(tagNumber, tag);
468500
}

src/lib/support/jsontlv/JsonToTlv.h

+8-4
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,14 @@ CHIP_ERROR JsonToTlv(const std::string & jsonString, MutableByteSpan & tlv);
3333
CHIP_ERROR JsonToTlv(const std::string & jsonString, TLV::TLVWriter & writer);
3434

3535
/*
36-
* Convert a uint64_t tagNumber to a TLV tag. When tagNumber is less than or equal to UINT8_MAX,
37-
* the tag is encoded using ContextTag. When tagNumber is larger than UINT8_MAX and less than or equal to UINT32_MAX,
38-
* the tag is encoded using an implicit profile tag.
36+
* Convert a uint32_t tagNumber (from MEI) to a TLV tag.
37+
* The upper 16 bits of tag_number represent the vendor_id.
38+
* The lower 16 bits of tag_number represent the tag_id.
39+
* When the MEI prefix encodes a standard/scoped source, the tag is encoded using ContextSpecific tag if tag_id is less than or
40+
* equal to UINT8_MAX, and ImplicitProfile tag if tag_id is larger than UINT8_MAX. When the MEI prefix encodes a manufacturer code,
41+
* the tag is encoded using FullyQualified_6Bytes tag, the Vendor ID SHALL be set to the manufacturer code, the profile number set
42+
* to 0 and the tag number set to the MEI suffix.
3943
*/
40-
CHIP_ERROR ConvertTlvTag(const uint64_t tagNumber, TLV::Tag & tag);
44+
CHIP_ERROR ConvertTlvTag(uint32_t tagNumber, TLV::Tag & tag);
4145

4246
} // namespace chip

src/lib/support/jsontlv/TlvToJson.cpp

+3-8
Original file line numberDiff line numberDiff line change
@@ -108,14 +108,12 @@ struct JsonObjectElementContext
108108
{
109109
if (TLV::ProfileIdFromTag(tag) == implicitProfileId)
110110
{
111-
// Explicit assume implicit tags are just things we want
112-
// 32-bit numbers for
113111
str = std::to_string(TLV::TagNumFromTag(tag));
114112
}
115113
else
116114
{
117-
// UNEXPECTED, create a full 64-bit number here
118-
str = std::to_string(TLV::ProfileIdFromTag(tag)) + "/" + std::to_string(TLV::TagNumFromTag(tag));
115+
uint32_t tagNumber = (static_cast<uint32_t>(TLV::VendorIdFromTag(tag)) << 16) | TLV::TagNumFromTag(tag);
116+
str = std::to_string(tagNumber);
119117
}
120118
}
121119
str = str + ":" + GetJsonElementStrFromType(type);
@@ -173,11 +171,8 @@ CHIP_ERROR TlvStructToJson(TLV::TLVReader & reader, Json::Value & jsonObj)
173171
TLV::Tag tag = reader.GetTag();
174172
VerifyOrReturnError(TLV::IsContextTag(tag) || TLV::IsProfileTag(tag), CHIP_ERROR_INVALID_TLV_TAG);
175173

176-
// Profile tags are expected to be implicit profile tags and they are
177-
// used to encode > 8bit values from json
178-
if (TLV::IsProfileTag(tag))
174+
if (TLV::IsProfileTag(tag) && TLV::VendorIdFromTag(tag) == 0)
179175
{
180-
VerifyOrReturnError(TLV::ProfileIdFromTag(tag) == reader.ImplicitProfileId, CHIP_ERROR_INVALID_TLV_TAG);
181176
VerifyOrReturnError(TLV::TagNumFromTag(tag) > UINT8_MAX, CHIP_ERROR_INVALID_TLV_TAG);
182177
}
183178

src/lib/support/tests/TestJsonToTlv.cpp

+72-1
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,7 @@ void Test32BitConvert(nlTestSuite * inSuite, void * inContext)
300300
NL_TEST_ASSERT(inSuite, reader.Next(TLV::AnonymousTag()) == CHIP_NO_ERROR);
301301
NL_TEST_ASSERT(inSuite, reader.GetType() == TLV::kTLVType_Structure);
302302
NL_TEST_ASSERT(inSuite, reader.EnterContainer(tlvType) == CHIP_NO_ERROR);
303-
NL_TEST_ASSERT(inSuite, reader.Next(TLV::ProfileTag(kImplicitProfileId, 0xFEDCBA98u)) == CHIP_NO_ERROR);
303+
NL_TEST_ASSERT(inSuite, reader.Next(TLV::ProfileTag((4275878552 >> 16) & 0xFFFF, 0, 4275878552 & 0xFFFF)) == CHIP_NO_ERROR);
304304
NL_TEST_ASSERT(inSuite, reader.GetType() == TLV::kTLVType_SignedInteger);
305305
NL_TEST_ASSERT(inSuite, reader.Get(value) == CHIP_NO_ERROR);
306306
NL_TEST_ASSERT(inSuite, value == 321);
@@ -312,6 +312,76 @@ void Test32BitConvert(nlTestSuite * inSuite, void * inContext)
312312
// FIXME: implement
313313
}
314314

315+
void TestMEIConvert(nlTestSuite * inSuite, void * inContext)
316+
{
317+
TLV::TLVReader reader;
318+
TLV::TLVType tlvType;
319+
int32_t value = 0;
320+
321+
// Vendor ID = 1, Tag ID = 0
322+
{
323+
SetupWriters();
324+
JsonToTlv("{\"65536:INT\": 321}", gWriter1);
325+
NL_TEST_ASSERT(inSuite, gWriter1.Finalize() == CHIP_NO_ERROR);
326+
327+
reader.Init(gBuf1, gWriter1.GetLengthWritten());
328+
reader.ImplicitProfileId = kImplicitProfileId;
329+
330+
NL_TEST_ASSERT(inSuite, reader.Next(TLV::AnonymousTag()) == CHIP_NO_ERROR);
331+
NL_TEST_ASSERT(inSuite, reader.GetType() == TLV::kTLVType_Structure);
332+
NL_TEST_ASSERT(inSuite, reader.EnterContainer(tlvType) == CHIP_NO_ERROR);
333+
NL_TEST_ASSERT(inSuite, reader.Next(TLV::ProfileTag(1, 0, 0)) == CHIP_NO_ERROR);
334+
NL_TEST_ASSERT(inSuite, reader.GetType() == TLV::kTLVType_SignedInteger);
335+
NL_TEST_ASSERT(inSuite, reader.Get(value) == CHIP_NO_ERROR);
336+
NL_TEST_ASSERT(inSuite, value == 321);
337+
NL_TEST_ASSERT(inSuite, reader.Next() == CHIP_END_OF_TLV);
338+
NL_TEST_ASSERT(inSuite, reader.ExitContainer(tlvType) == CHIP_NO_ERROR);
339+
NL_TEST_ASSERT(inSuite, reader.Next() == CHIP_END_OF_TLV);
340+
}
341+
342+
// Vendor ID = 0xFFFF, Tag ID = 0
343+
{
344+
SetupWriters();
345+
JsonToTlv("{\"4294901760:INT\": 123}", gWriter1);
346+
NL_TEST_ASSERT(inSuite, gWriter1.Finalize() == CHIP_NO_ERROR);
347+
348+
reader.Init(gBuf1, gWriter1.GetLengthWritten());
349+
reader.ImplicitProfileId = kImplicitProfileId;
350+
351+
NL_TEST_ASSERT(inSuite, reader.Next(TLV::AnonymousTag()) == CHIP_NO_ERROR);
352+
NL_TEST_ASSERT(inSuite, reader.GetType() == TLV::kTLVType_Structure);
353+
NL_TEST_ASSERT(inSuite, reader.EnterContainer(tlvType) == CHIP_NO_ERROR);
354+
NL_TEST_ASSERT(inSuite, reader.Next(TLV::ProfileTag(0xFFFF, 0, 0)) == CHIP_NO_ERROR);
355+
NL_TEST_ASSERT(inSuite, reader.GetType() == TLV::kTLVType_SignedInteger);
356+
NL_TEST_ASSERT(inSuite, reader.Get(value) == CHIP_NO_ERROR);
357+
NL_TEST_ASSERT(inSuite, value == 123);
358+
NL_TEST_ASSERT(inSuite, reader.Next() == CHIP_END_OF_TLV);
359+
NL_TEST_ASSERT(inSuite, reader.ExitContainer(tlvType) == CHIP_NO_ERROR);
360+
NL_TEST_ASSERT(inSuite, reader.Next() == CHIP_END_OF_TLV);
361+
}
362+
363+
// Vendor ID = 0xFFFF, Tag ID = 0xFFFF
364+
{
365+
SetupWriters();
366+
JsonToTlv("{\"4294967295:INT\": 123}", gWriter1);
367+
NL_TEST_ASSERT(inSuite, gWriter1.Finalize() == CHIP_NO_ERROR);
368+
369+
reader.Init(gBuf1, gWriter1.GetLengthWritten());
370+
reader.ImplicitProfileId = kImplicitProfileId;
371+
372+
NL_TEST_ASSERT(inSuite, reader.Next(TLV::AnonymousTag()) == CHIP_NO_ERROR);
373+
NL_TEST_ASSERT(inSuite, reader.GetType() == TLV::kTLVType_Structure);
374+
NL_TEST_ASSERT(inSuite, reader.EnterContainer(tlvType) == CHIP_NO_ERROR);
375+
NL_TEST_ASSERT(inSuite, reader.Next(TLV::ProfileTag(0xFFFF, 0, 0xFFFF)) == CHIP_NO_ERROR);
376+
NL_TEST_ASSERT(inSuite, reader.GetType() == TLV::kTLVType_SignedInteger);
377+
NL_TEST_ASSERT(inSuite, reader.Get(value) == CHIP_NO_ERROR);
378+
NL_TEST_ASSERT(inSuite, value == 123);
379+
NL_TEST_ASSERT(inSuite, reader.Next() == CHIP_END_OF_TLV);
380+
NL_TEST_ASSERT(inSuite, reader.ExitContainer(tlvType) == CHIP_NO_ERROR);
381+
NL_TEST_ASSERT(inSuite, reader.Next() == CHIP_END_OF_TLV);
382+
}
383+
}
384+
315385
int Initialize(void * apSuite)
316386
{
317387
VerifyOrReturnError(chip::Platform::MemoryInit() == CHIP_NO_ERROR, FAILURE);
@@ -329,6 +399,7 @@ const nlTest sTests[] =
329399
{
330400
NL_TEST_DEF("TestConverter", TestConverter),
331401
NL_TEST_DEF("Test32BitConvert", Test32BitConvert),
402+
NL_TEST_DEF("TestMEIConvert", TestMEIConvert),
332403
NL_TEST_SENTINEL()
333404
};
334405
// clang-format on

src/lib/support/tests/TestJsonToTlvToJson.cpp

+42-11
Original file line numberDiff line numberDiff line change
@@ -705,7 +705,8 @@ void TestConverter_Array_Empty_ImplicitProfileTag4(nlTestSuite * inSuite, void *
705705
NL_TEST_ASSERT(gSuite, CHIP_NO_ERROR == writer.StartContainer(TLV::AnonymousTag(), TLV::kTLVType_Structure, containerType));
706706
NL_TEST_ASSERT(gSuite,
707707
CHIP_NO_ERROR ==
708-
writer.StartContainer(TLV::ProfileTag(kImplicitProfileId, 1000000), TLV::kTLVType_Array, containerType2));
708+
writer.StartContainer(TLV::ProfileTag((1000000 >> 16) & 0xFFFF, 0, 1000000 & 0xFFFF), TLV::kTLVType_Array,
709+
containerType2));
709710
NL_TEST_ASSERT(gSuite, CHIP_NO_ERROR == writer.EndContainer(containerType2));
710711
NL_TEST_ASSERT(gSuite, CHIP_NO_ERROR == writer.EndContainer(containerType));
711712
NL_TEST_ASSERT(gSuite, CHIP_NO_ERROR == writer.Finalize());
@@ -1070,7 +1071,8 @@ void TestConverter_Array_Strings(nlTestSuite * inSuite, void * inContext)
10701071
NL_TEST_ASSERT(gSuite, CHIP_NO_ERROR == writer.StartContainer(TLV::AnonymousTag(), TLV::kTLVType_Structure, containerType));
10711072
NL_TEST_ASSERT(gSuite,
10721073
CHIP_NO_ERROR ==
1073-
writer.StartContainer(TLV::ProfileTag(kImplicitProfileId, 100000), TLV::kTLVType_Array, containerType2));
1074+
writer.StartContainer(TLV::ProfileTag((100000 >> 16) & 0xFFFF, 0, 100000 & 0xFFFF), TLV::kTLVType_Array,
1075+
containerType2));
10741076
NL_TEST_ASSERT(gSuite, CHIP_NO_ERROR == writer.PutString(TLV::AnonymousTag(), "ABC"));
10751077
NL_TEST_ASSERT(gSuite, CHIP_NO_ERROR == writer.PutString(TLV::AnonymousTag(), "Options"));
10761078
NL_TEST_ASSERT(gSuite, CHIP_NO_ERROR == writer.PutString(TLV::AnonymousTag(), "more"));
@@ -1202,11 +1204,10 @@ void TestConverter_Struct_MixedTags(nlTestSuite * inSuite, void * inContext)
12021204
NL_TEST_ASSERT(gSuite, CHIP_NO_ERROR == writer.StartContainer(TLV::AnonymousTag(), TLV::kTLVType_Structure, containerType));
12031205
NL_TEST_ASSERT(gSuite, CHIP_NO_ERROR == writer.StartContainer(TLV::ContextTag(0), TLV::kTLVType_Structure, containerType2));
12041206
NL_TEST_ASSERT(gSuite, CHIP_NO_ERROR == writer.Put(TLV::ContextTag(255), static_cast<uint64_t>(42)));
1207+
NL_TEST_ASSERT(gSuite, CHIP_NO_ERROR == writer.Put(TLV::ProfileTag(0x0001u, 0, 0), static_cast<uint64_t>(345678)));
12051208
NL_TEST_ASSERT(gSuite, CHIP_NO_ERROR == writer.Put(TLV::ProfileTag(kImplicitProfileId, 256), static_cast<uint64_t>(17000)));
1209+
NL_TEST_ASSERT(gSuite, CHIP_NO_ERROR == writer.Put(TLV::ProfileTag(0xFFFFu, 0, 0xFFFFu), static_cast<uint64_t>(500000000000)));
12061210
NL_TEST_ASSERT(gSuite, CHIP_NO_ERROR == writer.Put(TLV::ProfileTag(kImplicitProfileId, 65535), static_cast<uint64_t>(1)));
1207-
NL_TEST_ASSERT(gSuite, CHIP_NO_ERROR == writer.Put(TLV::ProfileTag(kImplicitProfileId, 65536), static_cast<uint64_t>(345678)));
1208-
NL_TEST_ASSERT(
1209-
gSuite, CHIP_NO_ERROR == writer.Put(TLV::ProfileTag(kImplicitProfileId, 4294967295), static_cast<uint64_t>(500000000000)));
12101211
NL_TEST_ASSERT(gSuite, CHIP_NO_ERROR == writer.EndContainer(containerType2));
12111212
NL_TEST_ASSERT(gSuite, CHIP_NO_ERROR == writer.EndContainer(containerType));
12121213
NL_TEST_ASSERT(gSuite, CHIP_NO_ERROR == writer.Finalize());
@@ -1706,7 +1707,7 @@ void TestConverter_TlvToJson_ErrorCases(nlTestSuite * inSuite, void * inContext)
17061707
uint8_t buf9[32];
17071708
writer.Init(buf9);
17081709
NL_TEST_ASSERT(inSuite, CHIP_NO_ERROR == writer.StartContainer(TLV::AnonymousTag(), TLV::kTLVType_Structure, containerType));
1709-
NL_TEST_ASSERT(inSuite, CHIP_NO_ERROR == writer.Put(TLV::ProfileTag(0xAA55FEED, 234), static_cast<uint64_t>(42)));
1710+
NL_TEST_ASSERT(inSuite, CHIP_NO_ERROR == writer.Put(TLV::ProfileTag(0xFEED, 234), static_cast<uint64_t>(42)));
17101711
NL_TEST_ASSERT(inSuite, CHIP_NO_ERROR == writer.EndContainer(containerType));
17111712
NL_TEST_ASSERT(inSuite, CHIP_NO_ERROR == writer.Finalize());
17121713
ByteSpan useFullyQualifiedTag(buf9, writer.GetLengthWritten());
@@ -1773,10 +1774,6 @@ void TestConverter_JsonToTlv_ErrorCases(nlTestSuite * inSuite, void * inContext)
17731774
" \"UINT\" : 42\n"
17741775
"}\n";
17751776

1776-
std::string invalidNameTagValueTooBig = "{\n"
1777-
" \"invalid:4294967296:UINT\" : 42\n"
1778-
"}\n";
1779-
17801777
std::string invalidNameWithNegativeTag = "{\n"
17811778
" \"-1:UINT\" : 42\n"
17821779
"}\n";
@@ -1814,7 +1811,6 @@ void TestConverter_JsonToTlv_ErrorCases(nlTestSuite * inSuite, void * inContext)
18141811
{ arrayElementsWithName, CHIP_ERROR_INTERNAL, "Array Elements With Json Name" },
18151812
{ invalidNameWithoutTagField, CHIP_ERROR_INVALID_ARGUMENT, "Invalid Name String Without Tag Field" },
18161813
{ invalidNameWithoutTagField2, CHIP_ERROR_INVALID_ARGUMENT, "Invalid Name String Without Tag Field 2" },
1817-
{ invalidNameTagValueTooBig, CHIP_ERROR_INVALID_ARGUMENT, "Invalid Name String Tag Value Larger than UINT32_MAX" },
18181814
{ invalidNameWithNegativeTag, CHIP_ERROR_INVALID_ARGUMENT, "Invalid Name With Negative Tag Value" },
18191815
{ invalidNameWithInvalidTypeField, CHIP_ERROR_INVALID_ARGUMENT, "Invalid Name With Invalid Type Field" },
18201816
{ invalidBytesBase64Value1, CHIP_ERROR_INVALID_ARGUMENT, "Invalid Base64 Encoding: Invalid Character" },
@@ -1834,6 +1830,40 @@ void TestConverter_JsonToTlv_ErrorCases(nlTestSuite * inSuite, void * inContext)
18341830
}
18351831
}
18361832

1833+
// Full Qualified Profile tags, Unsigned Integer structure: {65536 = 42, 4294901760 = 17000, 4294967295 = 500000000000}
1834+
void TestConverter_Struct_MEITags(nlTestSuite * inSuite, void * inContext)
1835+
{
1836+
gSuite = inSuite;
1837+
1838+
uint8_t buf[256];
1839+
TLV::TLVWriter writer;
1840+
TLV::TLVType containerType;
1841+
TLV::TLVType containerType2;
1842+
1843+
writer.Init(buf);
1844+
writer.ImplicitProfileId = kImplicitProfileId;
1845+
1846+
NL_TEST_ASSERT(gSuite, CHIP_NO_ERROR == writer.StartContainer(TLV::AnonymousTag(), TLV::kTLVType_Structure, containerType));
1847+
NL_TEST_ASSERT(gSuite, CHIP_NO_ERROR == writer.StartContainer(TLV::ContextTag(0), TLV::kTLVType_Structure, containerType2));
1848+
NL_TEST_ASSERT(gSuite, CHIP_NO_ERROR == writer.Put(TLV::ProfileTag(0xFFFFu, 0, 0), static_cast<uint64_t>(17000)));
1849+
NL_TEST_ASSERT(gSuite, CHIP_NO_ERROR == writer.Put(TLV::ProfileTag(0x0001u, 0, 0), static_cast<uint64_t>(42)));
1850+
NL_TEST_ASSERT(gSuite, CHIP_NO_ERROR == writer.Put(TLV::ProfileTag(0xFFFFu, 0, 0xFFFFu), static_cast<uint64_t>(500000000000)));
1851+
NL_TEST_ASSERT(gSuite, CHIP_NO_ERROR == writer.EndContainer(containerType2));
1852+
NL_TEST_ASSERT(gSuite, CHIP_NO_ERROR == writer.EndContainer(containerType));
1853+
NL_TEST_ASSERT(gSuite, CHIP_NO_ERROR == writer.Finalize());
1854+
1855+
std::string jsonString = "{\n"
1856+
" \"0:STRUCT\" : {\n"
1857+
" \"65536:UINT\" : 42,\n"
1858+
" \"4294901760:UINT\" : 17000,\n"
1859+
" \"4294967295:UINT\" : \"500000000000\"\n"
1860+
" }\n"
1861+
"}\n";
1862+
1863+
ByteSpan tlvSpan(buf, writer.GetLengthWritten());
1864+
CheckValidConversion(jsonString, tlvSpan, jsonString);
1865+
}
1866+
18371867
int Initialize(void * apSuite)
18381868
{
18391869
VerifyOrReturnError(chip::Platform::MemoryInit() == CHIP_NO_ERROR, FAILURE);
@@ -1899,6 +1929,7 @@ const nlTest sTests[] = {
18991929
NL_TEST_DEF("Test Json Tlv Converter - Complex Structure from the README File", TestConverter_Structure_FromReadme),
19001930
NL_TEST_DEF("Test Json Tlv Converter - Tlv to Json Error Cases", TestConverter_TlvToJson_ErrorCases),
19011931
NL_TEST_DEF("Test Json Tlv Converter - Json To Tlv Error Cases", TestConverter_JsonToTlv_ErrorCases),
1932+
NL_TEST_DEF("Test Json Tlv Converter - Structure with MEI Elements", TestConverter_Struct_MEITags),
19021933
NL_TEST_SENTINEL()
19031934
};
19041935

0 commit comments

Comments
 (0)