mirror of
https://github.com/espressif/openthread.git
synced 2026-08-07 03:07:47 +00:00
[mesh-forwarder] simplify GetFramePriority() (#5282)
This commit simplifies the `GetFramePriority()` implementation mainly avoiding copying of ICMP6/UDP header when possible. It also updates unit test `test-toolchain` to verify alignment behavior of packed structure.
This commit is contained in:
@@ -1242,12 +1242,11 @@ otError MeshForwarder::GetFramePriority(const uint8_t * aFrame,
|
||||
const Mac::Address &aMacDest,
|
||||
Message::Priority & aPriority)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
Ip6::Header ip6Header;
|
||||
Ip6::Udp::Header udpHeader;
|
||||
Ip6::Icmp::Header icmpHeader;
|
||||
uint8_t headerLength;
|
||||
bool nextHeaderCompressed;
|
||||
otError error = OT_ERROR_NONE;
|
||||
Ip6::Header ip6Header;
|
||||
uint16_t dstPort;
|
||||
uint8_t headerLength;
|
||||
bool nextHeaderCompressed;
|
||||
|
||||
SuccessOrExit(error = DecompressIp6Header(aFrame, aFrameLength, aMacSource, aMacDest, ip6Header, headerLength,
|
||||
nextHeaderCompressed));
|
||||
@@ -1256,35 +1255,46 @@ otError MeshForwarder::GetFramePriority(const uint8_t * aFrame,
|
||||
aFrame += headerLength;
|
||||
aFrameLength -= headerLength;
|
||||
|
||||
if (ip6Header.GetNextHeader() == Ip6::kProtoIcmp6 && aFrameLength)
|
||||
switch (ip6Header.GetNextHeader())
|
||||
{
|
||||
// Just check the first byte which is an ICMPv6 type.
|
||||
memcpy(&icmpHeader, aFrame, sizeof(icmpHeader.mType));
|
||||
case Ip6::kProtoIcmp6:
|
||||
|
||||
VerifyOrExit(aFrameLength >= sizeof(Ip6::Icmp::Header), error = OT_ERROR_PARSE);
|
||||
|
||||
// Only ICMPv6 error messages are prioritized.
|
||||
if (icmpHeader.IsError())
|
||||
if (reinterpret_cast<const Ip6::Icmp::Header *>(aFrame)->IsError())
|
||||
{
|
||||
aPriority = Message::kPriorityNet;
|
||||
}
|
||||
|
||||
ExitNow();
|
||||
}
|
||||
break;
|
||||
|
||||
VerifyOrExit(ip6Header.GetNextHeader() == Ip6::kProtoUdp, OT_NOOP);
|
||||
case Ip6::kProtoUdp:
|
||||
|
||||
if (nextHeaderCompressed)
|
||||
{
|
||||
VerifyOrExit(Get<Lowpan::Lowpan>().DecompressUdpHeader(udpHeader, aFrame, aFrameLength) >= 0, OT_NOOP);
|
||||
}
|
||||
else
|
||||
{
|
||||
VerifyOrExit(aFrameLength >= sizeof(Ip6::Udp::Header), error = OT_ERROR_PARSE);
|
||||
memcpy(&udpHeader, aFrame, sizeof(Ip6::Udp::Header));
|
||||
}
|
||||
if (nextHeaderCompressed)
|
||||
{
|
||||
Ip6::Udp::Header udpHeader;
|
||||
|
||||
if (udpHeader.GetDestinationPort() == Mle::kUdpPort || udpHeader.GetDestinationPort() == kCoapUdpPort)
|
||||
{
|
||||
aPriority = Message::kPriorityNet;
|
||||
VerifyOrExit(Get<Lowpan::Lowpan>().DecompressUdpHeader(udpHeader, aFrame, aFrameLength) >= 0,
|
||||
error = OT_ERROR_PARSE);
|
||||
|
||||
dstPort = udpHeader.GetDestinationPort();
|
||||
}
|
||||
else
|
||||
{
|
||||
VerifyOrExit(aFrameLength >= sizeof(Ip6::Udp::Header), error = OT_ERROR_PARSE);
|
||||
dstPort = reinterpret_cast<const Ip6::Udp::Header *>(aFrame)->GetDestinationPort();
|
||||
}
|
||||
|
||||
if ((dstPort == Mle::kUdpPort) || (dstPort == kCoapUdpPort))
|
||||
{
|
||||
aPriority = Message::kPriorityNet;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
exit:
|
||||
|
||||
@@ -41,7 +41,7 @@ uint32_t otNetifAddress_offset_mNext_c();
|
||||
otNetifAddress CreateNetif_c();
|
||||
}
|
||||
|
||||
void test_packed1()
|
||||
void test_packed1(void)
|
||||
{
|
||||
OT_TOOL_PACKED_BEGIN
|
||||
struct packed_t
|
||||
@@ -56,7 +56,7 @@ void test_packed1()
|
||||
VerifyOrQuit(sizeof(packed_t) == 7, "Toolchain::OT_TOOL_PACKED failed 1");
|
||||
}
|
||||
|
||||
void test_packed2()
|
||||
void test_packed2(void)
|
||||
{
|
||||
OT_TOOL_PACKED_BEGIN
|
||||
struct packed_t
|
||||
@@ -70,7 +70,7 @@ void test_packed2()
|
||||
VerifyOrQuit(sizeof(packed_t) == 4, "Toolchain::OT_TOOL_PACKED failed 2");
|
||||
}
|
||||
|
||||
void test_packed_union()
|
||||
void test_packed_union(void)
|
||||
{
|
||||
typedef struct
|
||||
{
|
||||
@@ -93,7 +93,7 @@ void test_packed_union()
|
||||
VerifyOrQuit(sizeof(packed_t) == 5, "Toolchain::OT_TOOL_PACKED failed 3");
|
||||
}
|
||||
|
||||
void test_packed_enum()
|
||||
void test_packed_enum(void)
|
||||
{
|
||||
ot::Neighbor neighbor;
|
||||
neighbor.SetState(ot::Neighbor::kStateValid);
|
||||
@@ -102,18 +102,68 @@ void test_packed_enum()
|
||||
VerifyOrQuit(neighbor.GetState() == ot::Neighbor::kStateValid, "Toolchain::OT_TOOL_PACKED failed 4");
|
||||
}
|
||||
|
||||
void test_addr_sizes()
|
||||
void test_addr_sizes(void)
|
||||
{
|
||||
VerifyOrQuit(offsetof(otNetifAddress, mNext) == otNetifAddress_offset_mNext_c(),
|
||||
"mNext should offset the same in C & C++");
|
||||
VerifyOrQuit(sizeof(otNetifAddress) == otNetifAddress_Size_c(), "otNetifAddress should the same in C & C++");
|
||||
}
|
||||
|
||||
void test_addr_bitfield()
|
||||
void test_addr_bitfield(void)
|
||||
{
|
||||
VerifyOrQuit(CreateNetif_c().mScopeOverrideValid == true, "Toolchain::test_addr_size_cpp");
|
||||
}
|
||||
|
||||
void test_packed_alignment(void)
|
||||
{
|
||||
OT_TOOL_PACKED_BEGIN
|
||||
struct PackedStruct
|
||||
{
|
||||
uint32_t mUint32;
|
||||
uint8_t mByte;
|
||||
uint16_t mUint16;
|
||||
} OT_TOOL_PACKED_END;
|
||||
|
||||
PackedStruct packedStruct;
|
||||
PackedStruct packedStructCopy;
|
||||
const uint8_t *packedStructBytes = reinterpret_cast<const uint8_t *>(&packedStruct);
|
||||
uint8_t buffer[sizeof(PackedStruct) * 2 + 1];
|
||||
|
||||
VerifyOrQuit(sizeof(PackedStruct) == 7, "Toolchain::OT_TOOL_PACKED failed");
|
||||
|
||||
packedStruct.mUint32 = 0x12345678;
|
||||
packedStruct.mByte = 0xfe;
|
||||
packedStruct.mUint16 = 0xabcd;
|
||||
|
||||
for (uint16_t start = 0; start < sizeof(PackedStruct); start++)
|
||||
{
|
||||
uint8_t *ptr = &buffer[start];
|
||||
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
|
||||
*reinterpret_cast<PackedStruct *>(ptr) = packedStruct;
|
||||
|
||||
for (uint16_t i = 0; i < start; i++)
|
||||
{
|
||||
VerifyOrQuit(buffer[i] == 0, "Toolchain::OT_TOOL_PACKED alignment failed - pre-size write");
|
||||
}
|
||||
|
||||
VerifyOrQuit(memcmp(ptr, packedStructBytes, sizeof(PackedStruct)) == 0,
|
||||
"Toolchain::OT_TOOL_PACKED alignment failed");
|
||||
|
||||
for (uint16_t i = start + sizeof(packedStruct); i < sizeof(buffer); i++)
|
||||
{
|
||||
VerifyOrQuit(buffer[i] == 0, "Toolchain::OT_TOOL_PACKED alignment failed - post-size write");
|
||||
}
|
||||
|
||||
memset(&packedStructCopy, 0, sizeof(PackedStruct));
|
||||
packedStructCopy = *reinterpret_cast<PackedStruct *>(ptr);
|
||||
|
||||
VerifyOrQuit(memcmp(&packedStructCopy, &packedStruct, sizeof(PackedStruct)) == 0,
|
||||
"Toolchain::OT_TOOL_PACKED failed - read error");
|
||||
}
|
||||
}
|
||||
|
||||
void TestToolchain(void)
|
||||
{
|
||||
test_packed1();
|
||||
@@ -122,6 +172,7 @@ void TestToolchain(void)
|
||||
test_packed_enum();
|
||||
test_addr_sizes();
|
||||
test_addr_bitfield();
|
||||
test_packed_alignment();
|
||||
}
|
||||
|
||||
int main(void)
|
||||
|
||||
Reference in New Issue
Block a user