mirror of
https://github.com/espressif/openthread.git
synced 2026-08-17 16:09:51 +00:00
[mac] update HasCslIe and refactor GetTimeIe for robust IE parsing (#13224)
This commit introduces two robustness improvements to Header Information Element (IE) parsing in Frame: 1. Aligned HasCslIe() with GetCslIe(): Previously, HasCslIe() returned true if a Header IE matching the CSL ID was present, regardless of whether its declared content length was valid (>= 4 bytes). Updating HasCslIe() to check GetCslIe() != nullptr ensures that presence checks enforce the same length validation as retrieval, preventing callers from assuming a malformed CSL IE is valid. 2. Robust Multi-Vendor IE Iteration in GetTimeIe(): GetTimeIe() previously retrieved the Vendor IE by matching ID 0x00 using GetHeaderIe(), which returns only the first matching element. If a frame contained multiple Vendor IEs (e.g., a standard Thread Vendor IE followed by a Nest Time Vendor IE), GetTimeIe() inspected only the first element, failed the OUI check, and returned nullptr. GetTimeIe() is refactored to iterate through all Header IEs until a matching Nest OUI and Time SubType are found, ensuring correct discovery across multi-vendor frames.
This commit is contained in:
+21
-10
@@ -1231,7 +1231,7 @@ exit:
|
||||
return;
|
||||
}
|
||||
|
||||
bool Frame::HasCslIe(void) const { return GetHeaderIe(CslIe::kHeaderIeId) != nullptr; }
|
||||
bool Frame::HasCslIe(void) const { return GetCslIe() != nullptr; }
|
||||
#endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
||||
|
||||
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE || OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
|
||||
@@ -1266,18 +1266,29 @@ exit:
|
||||
#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
|
||||
const TimeIe *Frame::GetTimeIe(void) const
|
||||
{
|
||||
const TimeIe *timeIe = nullptr;
|
||||
const uint8_t *cur = nullptr;
|
||||
uint16_t index = FindHeaderIeIndex();
|
||||
uint16_t payloadIndex = FindPayloadIndex();
|
||||
const TimeIe *timeIe = nullptr;
|
||||
|
||||
cur = GetHeaderIe(VendorIeHeader::kHeaderIeId);
|
||||
VerifyOrExit(cur != nullptr);
|
||||
VerifyOrExit(reinterpret_cast<const HeaderIe *>(cur)->GetLength() >= TimeIe::kIeContentSize);
|
||||
VerifyOrExit((index != kInvalidIndex) && (payloadIndex != kInvalidIndex));
|
||||
|
||||
cur += sizeof(HeaderIe);
|
||||
while (index < payloadIndex)
|
||||
{
|
||||
const HeaderIe *ie = reinterpret_cast<const HeaderIe *>(&mPsdu[index]);
|
||||
|
||||
timeIe = reinterpret_cast<const TimeIe *>(cur);
|
||||
VerifyOrExit(timeIe->GetVendorOui() == TimeIe::kVendorOuiNest, timeIe = nullptr);
|
||||
VerifyOrExit(timeIe->GetSubType() == TimeIe::kVendorIeTime, timeIe = nullptr);
|
||||
if ((ie->GetId() == VendorIeHeader::kHeaderIeId) && (ie->GetLength() >= TimeIe::kIeContentSize))
|
||||
{
|
||||
const TimeIe *vendorIe =
|
||||
reinterpret_cast<const TimeIe *>(reinterpret_cast<const uint8_t *>(ie) + sizeof(HeaderIe));
|
||||
if (vendorIe->GetVendorOui() == TimeIe::kVendorOuiNest && vendorIe->GetSubType() == TimeIe::kVendorIeTime)
|
||||
{
|
||||
timeIe = vendorIe;
|
||||
ExitNow();
|
||||
}
|
||||
}
|
||||
|
||||
index += sizeof(HeaderIe) + ie->GetLength();
|
||||
}
|
||||
|
||||
exit:
|
||||
return timeIe;
|
||||
|
||||
Reference in New Issue
Block a user