mirror of
https://github.com/espressif/openthread.git
synced 2026-06-06 05:24:51 +00:00
02aaf7cb73
This commit removes the `Tlv::ReadTlvValue()` method which is no longer needed or used. The same functionality is provided through the `Tlv::Info` class, specifically using its `ParseFrom()` and `ReadValue()` methods. This approach is safer and provides more comprehensive information about the parsed TLV. The unit tests are also updated to replace the usage of the removed method with the new `Tlv::Info` based approach.
499 lines
18 KiB
C++
499 lines
18 KiB
C++
/*
|
|
* Copyright (c) 2022, The OpenThread Authors.
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
* 3. Neither the name of the copyright holder nor the
|
|
* names of its contributors may be used to endorse or promote products
|
|
* derived from this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
* POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
#include "test_platform.h"
|
|
|
|
#include <openthread/config.h>
|
|
|
|
#include "common/message.hpp"
|
|
#include "common/tlvs.hpp"
|
|
#include "instance/instance.hpp"
|
|
|
|
#include "test_util.h"
|
|
#include "test_util.hpp"
|
|
|
|
namespace ot {
|
|
|
|
void TestTlv(void)
|
|
{
|
|
static constexpr uint16_t kMaxBufferSize = 300;
|
|
|
|
Instance *instance = testInitInstance();
|
|
Message *message;
|
|
Tlv tlv;
|
|
Tlv::Info tlvInfo;
|
|
ExtendedTlv extTlv;
|
|
Tlv::Bookmark bookmark;
|
|
uint16_t offset;
|
|
OffsetRange offsetRange;
|
|
uint16_t length;
|
|
uint16_t prevLength;
|
|
uint16_t index;
|
|
uint8_t buffer[kMaxBufferSize];
|
|
|
|
VerifyOrQuit(instance != nullptr);
|
|
|
|
VerifyOrQuit((message = instance->Get<MessagePool>().Allocate(Message::kTypeIp6)) != nullptr);
|
|
VerifyOrQuit(message != nullptr);
|
|
|
|
VerifyOrQuit(message->GetOffset() == 0);
|
|
VerifyOrQuit(message->GetLength() == 0);
|
|
|
|
VerifyOrQuit(Tlv::FindTlvValueOffsetRange(*message, /* aType */ 1, offsetRange) == kErrorNotFound);
|
|
VerifyOrQuit(tlvInfo.ParseFrom(*message, 0) == kErrorParse);
|
|
|
|
// Add an empty TLV with type 1 and check that we can find it
|
|
|
|
offset = message->GetLength();
|
|
|
|
tlv.SetType(1);
|
|
tlv.SetLength(0);
|
|
SuccessOrQuit(message->Append(tlv));
|
|
|
|
SuccessOrQuit(Tlv::FindTlvValueOffsetRange(*message, /* aType */ 1, offsetRange));
|
|
VerifyOrQuit(offsetRange.GetOffset() == sizeof(Tlv));
|
|
VerifyOrQuit(offsetRange.GetLength() == 0);
|
|
SuccessOrQuit(tlvInfo.ParseFrom(*message, offset));
|
|
VerifyOrQuit(tlvInfo.GetType() == 1);
|
|
VerifyOrQuit(tlvInfo.GetLength() == 0);
|
|
VerifyOrQuit(!tlvInfo.IsExtended());
|
|
VerifyOrQuit(tlvInfo.ReadValue(*message, buffer, 1) == kErrorParse);
|
|
|
|
// Add an empty extended TLV (type 2), and check that we can find it.
|
|
|
|
offset = message->GetLength();
|
|
|
|
extTlv.SetType(2);
|
|
extTlv.SetLength(0);
|
|
SuccessOrQuit(message->Append(extTlv));
|
|
|
|
SuccessOrQuit(Tlv::FindTlvValueOffsetRange(*message, /* aType */ 2, offsetRange));
|
|
VerifyOrQuit(offsetRange.GetOffset() == offset + sizeof(ExtendedTlv));
|
|
VerifyOrQuit(offsetRange.GetLength() == 0);
|
|
SuccessOrQuit(tlvInfo.ParseFrom(*message, offset));
|
|
VerifyOrQuit(tlvInfo.GetType() == 2);
|
|
VerifyOrQuit(tlvInfo.GetLength() == 0);
|
|
VerifyOrQuit(tlvInfo.IsExtended());
|
|
VerifyOrQuit(tlvInfo.ReadValue(*message, buffer, 1) == kErrorParse);
|
|
|
|
// Add a TLV with type 3 with one byte value and check if we can find it.
|
|
|
|
offset = message->GetLength();
|
|
|
|
tlv.SetType(3);
|
|
tlv.SetLength(1);
|
|
SuccessOrQuit(message->Append(tlv));
|
|
SuccessOrQuit(message->Append<uint8_t>(0xff));
|
|
|
|
SuccessOrQuit(Tlv::FindTlvValueOffsetRange(*message, /* aType */ 3, offsetRange));
|
|
VerifyOrQuit(offsetRange.GetOffset() == offset + sizeof(Tlv));
|
|
VerifyOrQuit(offsetRange.GetLength() == 1);
|
|
SuccessOrQuit(tlvInfo.ParseFrom(*message, offset));
|
|
VerifyOrQuit(tlvInfo.GetType() == 3);
|
|
VerifyOrQuit(tlvInfo.GetLength() == 1);
|
|
VerifyOrQuit(!tlvInfo.IsExtended());
|
|
SuccessOrQuit(tlvInfo.ReadValue(*message, buffer, 1));
|
|
VerifyOrQuit(buffer[0] == 0x0ff);
|
|
VerifyOrQuit(tlvInfo.ReadValue(*message, buffer, 2) == kErrorParse);
|
|
|
|
// Add an extended TLV with type 4 with two byte value and check if we can find it.
|
|
|
|
offset = message->GetLength();
|
|
|
|
extTlv.SetType(4);
|
|
extTlv.SetLength(2);
|
|
SuccessOrQuit(message->Append(extTlv));
|
|
SuccessOrQuit(message->Append<uint8_t>(0x12));
|
|
SuccessOrQuit(message->Append<uint8_t>(0x34));
|
|
|
|
SuccessOrQuit(Tlv::FindTlvValueOffsetRange(*message, /* aType */ 4, offsetRange));
|
|
VerifyOrQuit(offsetRange.GetOffset() == offset + sizeof(ExtendedTlv));
|
|
VerifyOrQuit(offsetRange.GetLength() == 2);
|
|
SuccessOrQuit(tlvInfo.ParseFrom(*message, offset));
|
|
VerifyOrQuit(tlvInfo.GetType() == 4);
|
|
VerifyOrQuit(tlvInfo.GetLength() == 2);
|
|
VerifyOrQuit(tlvInfo.IsExtended());
|
|
SuccessOrQuit(tlvInfo.ReadValue(*message, buffer, 1));
|
|
VerifyOrQuit(buffer[0] == 0x12);
|
|
SuccessOrQuit(tlvInfo.ReadValue(*message, buffer, 2));
|
|
VerifyOrQuit(buffer[0] == 0x12);
|
|
VerifyOrQuit(buffer[1] == 0x34);
|
|
VerifyOrQuit(tlvInfo.ReadValue(*message, buffer, 3) == kErrorParse);
|
|
|
|
// Add a TLV with missing value.
|
|
|
|
offset = message->GetLength();
|
|
|
|
tlv.SetType(5);
|
|
tlv.SetLength(1);
|
|
SuccessOrQuit(message->Append(tlv));
|
|
|
|
VerifyOrQuit(Tlv::FindTlvValueOffsetRange(*message, /* aType */ 5, offsetRange) != kErrorNone);
|
|
VerifyOrQuit(tlvInfo.ParseFrom(*message, offset) == kErrorParse);
|
|
|
|
// Add the missing value.
|
|
SuccessOrQuit(message->Append<uint8_t>(0xaa));
|
|
|
|
SuccessOrQuit(Tlv::FindTlvValueOffsetRange(*message, /* aType */ 5, offsetRange));
|
|
VerifyOrQuit(offsetRange.GetOffset() == offset + sizeof(Tlv));
|
|
VerifyOrQuit(offsetRange.GetLength() == 1);
|
|
SuccessOrQuit(tlvInfo.ParseFrom(*message, offset));
|
|
VerifyOrQuit(tlvInfo.GetType() == 5);
|
|
VerifyOrQuit(tlvInfo.GetLength() == 1);
|
|
VerifyOrQuit(!tlvInfo.IsExtended());
|
|
SuccessOrQuit(tlvInfo.ReadValue(*message, buffer, 1));
|
|
VerifyOrQuit(buffer[0] == 0xaa);
|
|
VerifyOrQuit(tlvInfo.ReadValue(*message, buffer, 2) == kErrorParse);
|
|
|
|
// Add an extended TLV with missing value.
|
|
|
|
offset = message->GetLength();
|
|
|
|
extTlv.SetType(6);
|
|
extTlv.SetLength(2);
|
|
SuccessOrQuit(message->Append(extTlv));
|
|
SuccessOrQuit(message->Append<uint8_t>(0xbb));
|
|
|
|
VerifyOrQuit(Tlv::FindTlvValueOffsetRange(*message, /* aType */ 6, offsetRange) != kErrorNone);
|
|
VerifyOrQuit(tlvInfo.ParseFrom(*message, offset) == kErrorParse);
|
|
|
|
SuccessOrQuit(message->Append<uint8_t>(0xcc));
|
|
|
|
SuccessOrQuit(Tlv::FindTlvValueOffsetRange(*message, /* aType */ 6, offsetRange) != kErrorNone);
|
|
VerifyOrQuit(offsetRange.GetOffset() == offset + sizeof(ExtendedTlv));
|
|
VerifyOrQuit(offsetRange.GetLength() == 2);
|
|
SuccessOrQuit(tlvInfo.ParseFrom(*message, offset));
|
|
VerifyOrQuit(tlvInfo.GetType() == 6);
|
|
VerifyOrQuit(tlvInfo.GetLength() == 2);
|
|
VerifyOrQuit(tlvInfo.IsExtended());
|
|
SuccessOrQuit(tlvInfo.ReadValue(*message, buffer, 2));
|
|
VerifyOrQuit(buffer[0] == 0xbb);
|
|
VerifyOrQuit(buffer[1] == 0xcc);
|
|
VerifyOrQuit(tlvInfo.ReadValue(*message, buffer, 3) == kErrorParse);
|
|
|
|
// Add an extended TLV with overflow length.
|
|
|
|
offset = message->GetLength();
|
|
|
|
extTlv.SetType(7);
|
|
extTlv.SetLength(0xffff);
|
|
SuccessOrQuit(message->Append(extTlv));
|
|
SuccessOrQuit(message->Append<uint8_t>(0x11));
|
|
|
|
VerifyOrQuit(Tlv::FindTlvValueOffsetRange(*message, /* aType */ 7, offsetRange) != kErrorNone);
|
|
VerifyOrQuit(tlvInfo.ParseFrom(*message, offset) == kErrorParse);
|
|
|
|
//- - - - - - - - - - - - - - - - - - - - - -
|
|
// Validate `StartTlv()`, `AdjustTlv()`, `EndTlv()`
|
|
|
|
SuccessOrQuit(message->SetLength(0));
|
|
offset = 0;
|
|
|
|
// Build a TLV with length 3
|
|
|
|
SuccessOrQuit(Tlv::StartTlv(*message, /* aType */ 1, bookmark));
|
|
SuccessOrQuit(message->Append<uint8_t>(0xab));
|
|
SuccessOrQuit(message->Append<uint8_t>(0xcd));
|
|
SuccessOrQuit(message->Append<uint8_t>(0xef));
|
|
SuccessOrQuit(Tlv::EndTlv(*message, bookmark));
|
|
|
|
SuccessOrQuit(Tlv::FindTlvValueOffsetRange(*message, /* aType */ 1, offsetRange));
|
|
VerifyOrQuit(offsetRange.GetOffset() == offset + sizeof(Tlv));
|
|
VerifyOrQuit(offsetRange.GetLength() == 3);
|
|
SuccessOrQuit(tlvInfo.ParseFrom(*message, offset));
|
|
VerifyOrQuit(tlvInfo.GetLength() == 3);
|
|
VerifyOrQuit(!tlvInfo.IsExtended());
|
|
SuccessOrQuit(tlvInfo.ReadValue(*message, buffer, 3));
|
|
VerifyOrQuit(buffer[0] == 0xab);
|
|
VerifyOrQuit(buffer[1] == 0xcd);
|
|
VerifyOrQuit(buffer[2] == 0xef);
|
|
|
|
offset = offsetRange.GetEndOffset();
|
|
VerifyOrQuit(offset == message->GetLength());
|
|
|
|
for (index = 0; index < kMaxBufferSize; index++)
|
|
{
|
|
buffer[index] = static_cast<uint8_t>(index);
|
|
}
|
|
|
|
// Build a TLV with length 254 (max for a regular TLV).
|
|
|
|
SuccessOrQuit(Tlv::StartTlv(*message, /* aType */ 2, bookmark));
|
|
SuccessOrQuit(message->AppendBytes(buffer, Tlv::kBaseTlvMaxLength));
|
|
SuccessOrQuit(Tlv::EndTlv(*message, bookmark));
|
|
|
|
SuccessOrQuit(Tlv::FindTlvValueOffsetRange(*message, /* aType */ 2, offsetRange));
|
|
VerifyOrQuit(offsetRange.GetOffset() == offset + sizeof(Tlv));
|
|
VerifyOrQuit(offsetRange.GetLength() == Tlv::kBaseTlvMaxLength);
|
|
VerifyOrQuit(message->CompareBytes(offsetRange, buffer));
|
|
|
|
offset = offsetRange.GetEndOffset();
|
|
VerifyOrQuit(offset == message->GetLength());
|
|
|
|
// Build a TLV with length 255 (ensure it is written as Extended TLV).
|
|
|
|
SuccessOrQuit(Tlv::StartTlv(*message, /* aType */ 3, bookmark));
|
|
SuccessOrQuit(message->AppendBytes(buffer, Tlv::kBaseTlvMaxLength + 1));
|
|
SuccessOrQuit(Tlv::EndTlv(*message, bookmark));
|
|
|
|
SuccessOrQuit(Tlv::FindTlvValueOffsetRange(*message, /* aType */ 3, offsetRange));
|
|
VerifyOrQuit(offsetRange.GetOffset() == offset + sizeof(ExtendedTlv));
|
|
VerifyOrQuit(offsetRange.GetLength() == Tlv::kBaseTlvMaxLength + 1);
|
|
VerifyOrQuit(message->CompareBytes(offsetRange, buffer));
|
|
|
|
offset = offsetRange.GetEndOffset();
|
|
VerifyOrQuit(offset == message->GetLength());
|
|
|
|
// Validate that `AdjustTlv()` copies the bytes only when we reach the
|
|
// TLV length limit.
|
|
|
|
SuccessOrQuit(Tlv::StartTlv(*message, /* aType */ 4, bookmark));
|
|
|
|
for (index = 0; index < Tlv::kBaseTlvMaxLength; index++)
|
|
{
|
|
SuccessOrQuit(message->Append<uint8_t>(buffer[index]));
|
|
|
|
prevLength = message->GetLength();
|
|
SuccessOrQuit(Tlv::AdjustTlv(*message, bookmark));
|
|
VerifyOrQuit(prevLength == message->GetLength());
|
|
}
|
|
|
|
SuccessOrQuit(message->Append<uint8_t>(buffer[index]));
|
|
index++;
|
|
|
|
prevLength = message->GetLength();
|
|
SuccessOrQuit(Tlv::AdjustTlv(*message, bookmark));
|
|
VerifyOrQuit(message->GetLength() == prevLength + sizeof(uint16_t));
|
|
|
|
for (; index < kMaxBufferSize; index++)
|
|
{
|
|
SuccessOrQuit(message->Append<uint8_t>(buffer[index]));
|
|
|
|
prevLength = message->GetLength();
|
|
SuccessOrQuit(Tlv::AdjustTlv(*message, bookmark));
|
|
VerifyOrQuit(prevLength == message->GetLength());
|
|
}
|
|
|
|
SuccessOrQuit(Tlv::EndTlv(*message, bookmark));
|
|
|
|
SuccessOrQuit(Tlv::FindTlvValueOffsetRange(*message, /* aType */ 4, offsetRange));
|
|
VerifyOrQuit(offsetRange.GetOffset() == offset + sizeof(ExtendedTlv));
|
|
VerifyOrQuit(offsetRange.GetLength() == kMaxBufferSize);
|
|
VerifyOrQuit(message->CompareBytes(offsetRange, buffer));
|
|
|
|
offset = offsetRange.GetEndOffset();
|
|
VerifyOrQuit(offset == message->GetLength());
|
|
|
|
message->Free();
|
|
|
|
testFreeInstance(instance);
|
|
}
|
|
|
|
void TestTlvInfo(void)
|
|
{
|
|
Instance *instance;
|
|
Message *message;
|
|
uint16_t offset;
|
|
uint16_t len;
|
|
Tlv tlv;
|
|
ExtendedTlv extTlv;
|
|
Tlv::Info info;
|
|
|
|
instance = testInitInstance();
|
|
VerifyOrQuit(instance != nullptr);
|
|
message = instance->Get<MessagePool>().Allocate(Message::kTypeOther);
|
|
VerifyOrQuit(message != nullptr);
|
|
|
|
// Append TLV 1: Standard TLV with 1-byte value.
|
|
tlv.SetType(1);
|
|
tlv.SetLength(1);
|
|
SuccessOrQuit(message->Append(tlv));
|
|
SuccessOrQuit(message->Append<uint8_t>(0xaa));
|
|
|
|
// Append TLV 2: Extended TLV with 2-byte value.
|
|
extTlv.SetType(2);
|
|
extTlv.SetLength(2);
|
|
SuccessOrQuit(message->Append(extTlv));
|
|
SuccessOrQuit(message->Append<uint16_t>(0xcafe));
|
|
|
|
// Append TLV 3: Standard empty TLV.
|
|
tlv.SetType(3);
|
|
tlv.SetLength(0);
|
|
SuccessOrQuit(message->Append(tlv));
|
|
|
|
// Append TLV 4: Extended empty TLV.
|
|
extTlv.SetType(4);
|
|
extTlv.SetLength(0);
|
|
SuccessOrQuit(message->Append(extTlv));
|
|
|
|
// Append TLV 5: Malformed standard TLV (claims length 2, but has only 1).
|
|
tlv.SetType(5);
|
|
tlv.SetLength(2);
|
|
SuccessOrQuit(message->Append(tlv));
|
|
SuccessOrQuit(message->Append<uint8_t>(0x12));
|
|
|
|
for (uint8_t testIter = 0; testIter <= 1; testIter++)
|
|
{
|
|
offset = 0;
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
// TLV 1 (standard, len=1)
|
|
|
|
len = 1;
|
|
|
|
if (testIter == 0)
|
|
{
|
|
SuccessOrQuit(info.ParseFrom(*message, offset));
|
|
}
|
|
else
|
|
{
|
|
SuccessOrQuit(info.FindIn(*message, 1));
|
|
}
|
|
|
|
VerifyOrQuit(info.GetType() == 1);
|
|
VerifyOrQuit(info.GetLength() == len);
|
|
VerifyOrQuit(!info.IsExtended());
|
|
VerifyOrQuit(info.GetSize() == sizeof(Tlv) + len);
|
|
VerifyOrQuit(info.GetTlvOffset() == offset);
|
|
VerifyOrQuit(info.GetValueOffset() == offset + sizeof(Tlv));
|
|
VerifyOrQuit(info.GetTlvOffsetRange().GetOffset() == offset);
|
|
VerifyOrQuit(info.GetTlvOffsetRange().GetLength() == sizeof(Tlv) + len);
|
|
VerifyOrQuit(info.GetValueOffsetRange().GetOffset() == offset + sizeof(Tlv));
|
|
VerifyOrQuit(info.GetValueOffsetRange().GetLength() == len);
|
|
|
|
offset = info.GetTlvOffsetRange().GetEndOffset();
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
// TLV 2 (extended, len=2)
|
|
|
|
len = 2;
|
|
|
|
if (testIter == 0)
|
|
{
|
|
SuccessOrQuit(info.ParseFrom(*message, offset));
|
|
}
|
|
else
|
|
{
|
|
SuccessOrQuit(info.FindIn(*message, 2));
|
|
}
|
|
|
|
VerifyOrQuit(info.GetType() == 2);
|
|
VerifyOrQuit(info.GetLength() == len);
|
|
VerifyOrQuit(info.IsExtended());
|
|
VerifyOrQuit(info.GetSize() == sizeof(ExtendedTlv) + len);
|
|
VerifyOrQuit(info.GetTlvOffset() == offset);
|
|
VerifyOrQuit(info.GetValueOffset() == offset + sizeof(ExtendedTlv));
|
|
VerifyOrQuit(info.GetTlvOffsetRange().GetOffset() == offset);
|
|
VerifyOrQuit(info.GetTlvOffsetRange().GetLength() == sizeof(ExtendedTlv) + len);
|
|
VerifyOrQuit(info.GetValueOffsetRange().GetOffset() == offset + sizeof(ExtendedTlv));
|
|
VerifyOrQuit(info.GetValueOffsetRange().GetLength() == len);
|
|
|
|
offset = info.GetTlvOffsetRange().GetEndOffset();
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
// TLV 3 (standard, empty)
|
|
|
|
len = 0;
|
|
|
|
if (testIter == 0)
|
|
{
|
|
SuccessOrQuit(info.ParseFrom(*message, offset));
|
|
}
|
|
else
|
|
{
|
|
SuccessOrQuit(info.FindIn(*message, 3));
|
|
}
|
|
|
|
VerifyOrQuit(info.GetType() == 3);
|
|
VerifyOrQuit(info.GetLength() == len);
|
|
VerifyOrQuit(!info.IsExtended());
|
|
VerifyOrQuit(info.GetSize() == sizeof(Tlv) + len);
|
|
VerifyOrQuit(info.GetTlvOffset() == offset);
|
|
VerifyOrQuit(info.GetValueOffset() == offset + sizeof(Tlv));
|
|
VerifyOrQuit(info.GetTlvOffsetRange().GetOffset() == offset);
|
|
VerifyOrQuit(info.GetTlvOffsetRange().GetLength() == sizeof(Tlv) + len);
|
|
VerifyOrQuit(info.GetValueOffsetRange().GetOffset() == offset + sizeof(Tlv));
|
|
VerifyOrQuit(info.GetValueOffsetRange().GetLength() == len);
|
|
|
|
offset = info.GetTlvOffsetRange().GetEndOffset();
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
// TLV 4 (extended, empty)
|
|
|
|
len = 0;
|
|
|
|
if (testIter == 0)
|
|
{
|
|
SuccessOrQuit(info.ParseFrom(*message, offset));
|
|
}
|
|
else
|
|
{
|
|
SuccessOrQuit(info.FindIn(*message, 4));
|
|
}
|
|
|
|
VerifyOrQuit(info.GetType() == 4);
|
|
VerifyOrQuit(info.GetLength() == len);
|
|
VerifyOrQuit(info.IsExtended());
|
|
VerifyOrQuit(info.GetSize() == sizeof(ExtendedTlv) + len);
|
|
VerifyOrQuit(info.GetTlvOffset() == offset);
|
|
VerifyOrQuit(info.GetValueOffset() == offset + sizeof(ExtendedTlv));
|
|
VerifyOrQuit(info.GetTlvOffsetRange().GetOffset() == offset);
|
|
VerifyOrQuit(info.GetTlvOffsetRange().GetLength() == sizeof(ExtendedTlv) + len);
|
|
VerifyOrQuit(info.GetValueOffsetRange().GetOffset() == offset + sizeof(ExtendedTlv));
|
|
VerifyOrQuit(info.GetValueOffsetRange().GetLength() == len);
|
|
|
|
offset = info.GetTlvOffsetRange().GetEndOffset();
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
// Test TLV 5 (malformed)
|
|
|
|
if (testIter == 0)
|
|
{
|
|
VerifyOrQuit(info.ParseFrom(*message, offset) == kErrorParse);
|
|
}
|
|
else
|
|
{
|
|
VerifyOrQuit(info.FindIn(*message, 5) != kErrorNone);
|
|
}
|
|
}
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
message->Free();
|
|
testFreeInstance(instance);
|
|
}
|
|
|
|
} // namespace ot
|
|
|
|
int main(void)
|
|
{
|
|
ot::TestTlv();
|
|
ot::TestTlvInfo();
|
|
printf("All tests passed\n");
|
|
return 0;
|
|
}
|