mirror of
https://github.com/espressif/openthread.git
synced 2026-07-07 21:00:20 +00:00
8abf9667c3
This commit refactors the `FrameBuilder` and `FrameData` modules, replacing multiple distinct endian-specific methods with a unified, type-safe templated API. Key changes: - Introduced `enum Encoding` (`kBigEndian`, `kLittleEndian`) and a templated `HostSwap<Encoding, UintType>` helper in `encoding.hpp` to centralize byte-swapping logic. - Replaced `AppendBigEndianUint16()`, `AppendLittleEndianUint32()`, and other variations in `FrameBuilder` with a single templated method: `AppendUint<Encoding, UintType>()`. - Replaced `ReadBigEndianUint16()`, `ReadLittleEndianUint32()`, and other variations in `FrameData` with a single templated method: `ReadUint<Encoding, UintType>()`. - Updated all callers in `Lowpan` and `Mac` modules to use the new templated encoding APIs. - Updated `test_frame_builder.cpp` to validate the new syntax.
231 lines
10 KiB
C++
231 lines
10 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 <openthread/config.h>
|
|
|
|
#include "test_platform.h"
|
|
#include "test_util.hpp"
|
|
|
|
#include "common/frame_builder.hpp"
|
|
|
|
namespace ot {
|
|
|
|
void TestFrameBuilder(void)
|
|
{
|
|
const uint8_t kData1[] = {0x01, 0x02, 0x03, 0x04, 0x05};
|
|
const uint8_t kData2[] = {0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa};
|
|
const uint8_t kData3[] = {0xca, 0xfe, 0xbe, 0xef};
|
|
|
|
static constexpr uint16_t kMaxBufferSize = sizeof(kData1) * 2 + sizeof(kData2);
|
|
|
|
Instance *instance;
|
|
Message *message;
|
|
uint16_t offset;
|
|
uint8_t buffer[kMaxBufferSize];
|
|
uint8_t zeroBuffer[kMaxBufferSize];
|
|
FrameBuilder frameBuilder;
|
|
uint16_t u16;
|
|
uint32_t u32;
|
|
|
|
printf("TestFrameBuilder\n");
|
|
|
|
instance = static_cast<Instance *>(testInitInstance());
|
|
VerifyOrQuit(instance != nullptr);
|
|
|
|
message = instance->Get<MessagePool>().Allocate(Message::kTypeIp6);
|
|
VerifyOrQuit(message != nullptr);
|
|
|
|
SuccessOrQuit(message->Append(kData1));
|
|
SuccessOrQuit(message->Append(kData2));
|
|
|
|
memset(buffer, 0, sizeof(buffer));
|
|
memset(zeroBuffer, 0, sizeof(zeroBuffer));
|
|
|
|
frameBuilder.Init(buffer, sizeof(buffer));
|
|
|
|
VerifyOrQuit(frameBuilder.GetBytes() == buffer);
|
|
VerifyOrQuit(frameBuilder.GetLength() == 0);
|
|
VerifyOrQuit(frameBuilder.GetMaxLength() == sizeof(buffer));
|
|
VerifyOrQuit(memcmp(buffer, zeroBuffer, sizeof(buffer)) == 0);
|
|
VerifyOrQuit(frameBuilder.CanAppend(sizeof(buffer)));
|
|
VerifyOrQuit(!frameBuilder.CanAppend(sizeof(buffer) + 1));
|
|
|
|
frameBuilder.SetMaxLength(sizeof(kData1));
|
|
VerifyOrQuit(frameBuilder.GetBytes() == buffer);
|
|
VerifyOrQuit(frameBuilder.GetLength() == 0);
|
|
VerifyOrQuit(frameBuilder.GetMaxLength() == sizeof(kData1));
|
|
VerifyOrQuit(memcmp(buffer, zeroBuffer, sizeof(buffer)) == 0);
|
|
VerifyOrQuit(frameBuilder.CanAppend(sizeof(kData1)));
|
|
VerifyOrQuit(!frameBuilder.CanAppend(sizeof(kData1) + 1));
|
|
|
|
SuccessOrQuit(frameBuilder.Append(kData1));
|
|
VerifyOrQuit(frameBuilder.GetLength() == sizeof(kData1));
|
|
VerifyOrQuit(frameBuilder.GetBytes() == buffer);
|
|
VerifyOrQuit(memcmp(buffer, kData1, sizeof(kData1)) == 0);
|
|
VerifyOrQuit(memcmp(buffer + sizeof(kData1), zeroBuffer, sizeof(buffer) - sizeof(kData1)) == 0);
|
|
|
|
frameBuilder.SetMaxLength(sizeof(buffer));
|
|
VerifyOrQuit(frameBuilder.GetMaxLength() == sizeof(buffer));
|
|
VerifyOrQuit(frameBuilder.CanAppend(sizeof(buffer) - sizeof(kData1)));
|
|
VerifyOrQuit(!frameBuilder.CanAppend(sizeof(buffer) - sizeof(kData1) + 1));
|
|
|
|
SuccessOrQuit(frameBuilder.AppendUint8(0x01));
|
|
u16 = 0x203;
|
|
SuccessOrQuit(frameBuilder.AppendUint<kBigEndian>(u16));
|
|
u16 = 0x0504;
|
|
SuccessOrQuit(frameBuilder.AppendUint<kLittleEndian>(u16));
|
|
VerifyOrQuit(frameBuilder.GetLength() == sizeof(kData1) * 2);
|
|
VerifyOrQuit(frameBuilder.GetBytes() == buffer);
|
|
VerifyOrQuit(memcmp(buffer, kData1, sizeof(kData1)) == 0);
|
|
VerifyOrQuit(memcmp(buffer + sizeof(kData1), kData1, sizeof(kData1)) == 0);
|
|
|
|
u32 = 0x01020304;
|
|
SuccessOrQuit(frameBuilder.AppendUint<kBigEndian>(u32));
|
|
SuccessOrQuit(frameBuilder.AppendUint8(0x05));
|
|
VerifyOrQuit(frameBuilder.GetLength() == sizeof(kData1) * 3);
|
|
VerifyOrQuit(frameBuilder.GetBytes() == buffer);
|
|
VerifyOrQuit(memcmp(buffer, kData1, sizeof(kData1)) == 0);
|
|
VerifyOrQuit(memcmp(buffer + sizeof(kData1), kData1, sizeof(kData1)) == 0);
|
|
VerifyOrQuit(memcmp(buffer + 2 * sizeof(kData1), kData1, sizeof(kData1)) == 0);
|
|
|
|
frameBuilder.Init(buffer, sizeof(buffer));
|
|
VerifyOrQuit(frameBuilder.GetBytes() == buffer);
|
|
VerifyOrQuit(frameBuilder.GetLength() == 0);
|
|
VerifyOrQuit(frameBuilder.GetMaxLength() == sizeof(buffer));
|
|
|
|
offset = sizeof(kData1);
|
|
SuccessOrQuit(frameBuilder.AppendBytesFromMessage(*message, offset, sizeof(kData2)));
|
|
VerifyOrQuit(frameBuilder.GetLength() == sizeof(kData2));
|
|
VerifyOrQuit(frameBuilder.GetBytes() == buffer);
|
|
VerifyOrQuit(memcmp(buffer, kData2, sizeof(kData2)) == 0);
|
|
|
|
frameBuilder.Init(buffer, sizeof(buffer));
|
|
VerifyOrQuit(frameBuilder.GetBytes() == buffer);
|
|
VerifyOrQuit(frameBuilder.GetLength() == 0);
|
|
VerifyOrQuit(frameBuilder.GetMaxLength() == sizeof(buffer));
|
|
|
|
u32 = 0x04030201;
|
|
SuccessOrQuit(frameBuilder.AppendUint<kLittleEndian>(u32));
|
|
SuccessOrQuit(frameBuilder.AppendUint8(0x05));
|
|
VerifyOrQuit(frameBuilder.GetLength() == sizeof(kData1));
|
|
VerifyOrQuit(frameBuilder.GetBytes() == buffer);
|
|
VerifyOrQuit(memcmp(buffer, kData1, sizeof(kData1)) == 0);
|
|
|
|
SuccessOrQuit(frameBuilder.AppendBytes(zeroBuffer, sizeof(kData2)));
|
|
SuccessOrQuit(frameBuilder.Append(kData1));
|
|
VerifyOrQuit(frameBuilder.GetLength() == sizeof(buffer));
|
|
VerifyOrQuit(frameBuilder.GetBytes() == buffer);
|
|
VerifyOrQuit(memcmp(buffer, kData1, sizeof(kData1)) == 0);
|
|
VerifyOrQuit(memcmp(buffer + sizeof(kData1), zeroBuffer, sizeof(kData2)) == 0);
|
|
VerifyOrQuit(memcmp(buffer + sizeof(kData1) + sizeof(kData2), kData1, sizeof(kData1)) == 0);
|
|
|
|
VerifyOrQuit(!frameBuilder.CanAppend(1));
|
|
VerifyOrQuit(frameBuilder.AppendUint8(0x00) == kErrorNoBufs);
|
|
|
|
offset = sizeof(kData1);
|
|
frameBuilder.Write(offset, kData2);
|
|
VerifyOrQuit(frameBuilder.GetLength() == sizeof(buffer));
|
|
VerifyOrQuit(frameBuilder.GetBytes() == buffer);
|
|
VerifyOrQuit(memcmp(buffer, kData1, sizeof(kData1)) == 0);
|
|
VerifyOrQuit(memcmp(buffer + sizeof(kData1), kData2, sizeof(kData2)) == 0);
|
|
VerifyOrQuit(memcmp(buffer + sizeof(kData1) + sizeof(kData2), kData1, sizeof(kData1)) == 0);
|
|
|
|
frameBuilder.Init(buffer, sizeof(buffer));
|
|
VerifyOrQuit(frameBuilder.GetBytes() == buffer);
|
|
VerifyOrQuit(frameBuilder.GetLength() == 0);
|
|
VerifyOrQuit(frameBuilder.GetMaxLength() == sizeof(buffer));
|
|
|
|
offset = 0;
|
|
SuccessOrQuit(frameBuilder.Insert(offset, kData1));
|
|
VerifyOrQuit(frameBuilder.GetLength() == sizeof(kData1));
|
|
VerifyOrQuit(frameBuilder.GetBytes() == buffer);
|
|
VerifyOrQuit(memcmp(buffer, kData1, sizeof(kData1)) == 0);
|
|
|
|
offset = 0;
|
|
SuccessOrQuit(frameBuilder.Insert(offset, kData2));
|
|
VerifyOrQuit(frameBuilder.GetLength() == sizeof(kData1) + sizeof(kData2));
|
|
VerifyOrQuit(frameBuilder.GetBytes() == buffer);
|
|
VerifyOrQuit(memcmp(buffer, kData2, sizeof(kData2)) == 0);
|
|
VerifyOrQuit(memcmp(buffer + sizeof(kData2), kData1, sizeof(kData1)) == 0);
|
|
|
|
offset = sizeof(kData2);
|
|
SuccessOrQuit(frameBuilder.InsertBytes(offset, kData3, sizeof(kData3)));
|
|
VerifyOrQuit(frameBuilder.GetLength() == sizeof(kData1) + sizeof(kData2) + sizeof(kData3));
|
|
VerifyOrQuit(frameBuilder.GetBytes() == buffer);
|
|
VerifyOrQuit(memcmp(buffer, kData2, sizeof(kData2)) == 0);
|
|
VerifyOrQuit(memcmp(buffer + sizeof(kData2), kData3, sizeof(kData3)) == 0);
|
|
VerifyOrQuit(memcmp(buffer + sizeof(kData2) + sizeof(kData3), kData1, sizeof(kData1)) == 0);
|
|
|
|
offset = frameBuilder.GetLength();
|
|
SuccessOrQuit(frameBuilder.Insert<uint8_t>(offset, 0x77));
|
|
VerifyOrQuit(frameBuilder.GetLength() == sizeof(kData1) + sizeof(kData2) + sizeof(kData3) + sizeof(uint8_t));
|
|
VerifyOrQuit(frameBuilder.GetBytes() == buffer);
|
|
VerifyOrQuit(memcmp(buffer, kData2, sizeof(kData2)) == 0);
|
|
VerifyOrQuit(memcmp(buffer + sizeof(kData2), kData3, sizeof(kData3)) == 0);
|
|
VerifyOrQuit(memcmp(buffer + sizeof(kData2) + sizeof(kData3), kData1, sizeof(kData1)) == 0);
|
|
VerifyOrQuit(buffer[sizeof(kData2) + sizeof(kData3) + sizeof(kData1)] == 0x77);
|
|
|
|
offset = frameBuilder.GetLength() - 1;
|
|
frameBuilder.RemoveBytes(offset, sizeof(uint8_t));
|
|
VerifyOrQuit(frameBuilder.GetLength() == sizeof(kData1) + sizeof(kData2) + sizeof(kData3));
|
|
VerifyOrQuit(frameBuilder.GetBytes() == buffer);
|
|
VerifyOrQuit(memcmp(buffer, kData2, sizeof(kData2)) == 0);
|
|
VerifyOrQuit(memcmp(buffer + sizeof(kData2), kData3, sizeof(kData3)) == 0);
|
|
VerifyOrQuit(memcmp(buffer + sizeof(kData2) + sizeof(kData3), kData1, sizeof(kData1)) == 0);
|
|
|
|
offset = sizeof(kData2);
|
|
frameBuilder.RemoveBytes(offset, sizeof(kData3));
|
|
VerifyOrQuit(frameBuilder.GetLength() == sizeof(kData1) + sizeof(kData2));
|
|
VerifyOrQuit(frameBuilder.GetBytes() == buffer);
|
|
VerifyOrQuit(memcmp(buffer, kData2, sizeof(kData2)) == 0);
|
|
VerifyOrQuit(memcmp(buffer + sizeof(kData2), kData1, sizeof(kData1)) == 0);
|
|
|
|
offset = 0;
|
|
frameBuilder.RemoveBytes(offset, sizeof(kData2));
|
|
VerifyOrQuit(frameBuilder.GetLength() == sizeof(kData1));
|
|
VerifyOrQuit(frameBuilder.GetBytes() == buffer);
|
|
VerifyOrQuit(memcmp(buffer, kData1, sizeof(kData1)) == 0);
|
|
|
|
offset = 0;
|
|
frameBuilder.RemoveBytes(offset, sizeof(kData1));
|
|
VerifyOrQuit(frameBuilder.GetLength() == 0);
|
|
|
|
message->Free();
|
|
testFreeInstance(instance);
|
|
}
|
|
|
|
} // namespace ot
|
|
|
|
int main(void)
|
|
{
|
|
ot::TestFrameBuilder();
|
|
|
|
printf("All tests passed\n");
|
|
return 0;
|
|
}
|