mirror of
https://github.com/espressif/openthread.git
synced 2026-08-21 18:09:52 +00:00
[mac] redesign Information Element (IE) processing and generation (#13263)
This commit redesigns IEEE 802.15.4 Information Element (IE) handling by introducing dedicated subclass definitions (`CslIe`, `TimeIe`, `ConnectionIe`, `RendezvousTimeIe`, `LinkMetricsProbingIe`, etc.) inheriting from `HeaderIe` or `VendorIe`. In addition, `Mac::Frame` is updated with generic template methods: - `Has<IeType>()`: Checks if the frame contains a well-formed instance of the specified IE subclass. - `Find<IeType>()`: Finds, validates and returns a type-safe pointer to the IE. Key benefits of this redesign: - Streamlined IE Generation: Constructing and populating IEs is significantly simplified. Each subclass exposes a unified `Init()` method that cleanly computes the exact IE content length, sets the Element ID and known content (e.g. vendor OUI) in a single step. - True Encapsulation: Each IE subclass serves as the single source of truth for its Element ID (`kId`), content layout, and structural validation logic (`IsValid()`). Callers no longer pass magic ID constants or perform error-prone pointer arithmetic. - By implementing `HeaderIe::ValidateAs<IeType>()` as a static polymorphic matcher passed to `FindHeaderIe()`, the compiler devirtualizes and inlines ID match and content verifications directly into MAC frame parsing loops. - Scalable Integration: Adding new Information Elements is trivial. Defining a new subclass automatically equips MAC frame handling with type-safe search without bloating `Mac::Frame` with ad-hoc getter methods.
This commit is contained in:
@@ -205,7 +205,7 @@ otError otMacFrameGenerateEnhAck(const otRadioFrame *aFrame,
|
||||
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
||||
void otMacFrameSetCslIe(otRadioFrame *aFrame, uint16_t aCslPeriod, uint16_t aCslPhase)
|
||||
{
|
||||
static_cast<Mac::Frame *>(aFrame)->SetCslIe(aCslPeriod, aCslPhase);
|
||||
static_cast<Mac::Frame *>(aFrame)->UpdateCslIe(aCslPeriod, aCslPhase);
|
||||
}
|
||||
#endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
||||
|
||||
@@ -264,42 +264,37 @@ uint8_t otMacFrameGenerateCslIeTemplate(uint8_t *aDest)
|
||||
{
|
||||
assert(aDest != nullptr);
|
||||
|
||||
reinterpret_cast<Mac::HeaderIe *>(aDest)->Init(Mac::CslIe::kHeaderIeId, sizeof(Mac::CslIe));
|
||||
reinterpret_cast<Mac::CslIe *>(aDest)->Init();
|
||||
|
||||
return sizeof(Mac::HeaderIe) + sizeof(Mac::CslIe);
|
||||
return sizeof(Mac::CslIe);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
|
||||
uint8_t otMacFrameGenerateEnhAckProbingIe(uint8_t *aDest, const uint8_t *aIeData, uint8_t aIeDataLength)
|
||||
{
|
||||
uint8_t len = sizeof(Mac::VendorIeHeader) + aIeDataLength;
|
||||
Mac::LinkMetricsProbingIe *probingIe = reinterpret_cast<Mac::LinkMetricsProbingIe *>(aDest);
|
||||
|
||||
assert(aDest != nullptr);
|
||||
|
||||
reinterpret_cast<Mac::HeaderIe *>(aDest)->Init(Mac::ThreadIe::kHeaderIeId, len);
|
||||
|
||||
aDest += sizeof(Mac::HeaderIe);
|
||||
|
||||
reinterpret_cast<Mac::VendorIeHeader *>(aDest)->SetVendorOui(Mac::ThreadIe::kVendorOuiThreadCompanyId);
|
||||
reinterpret_cast<Mac::VendorIeHeader *>(aDest)->SetSubType(Mac::ThreadIe::kEnhAckProbingIe);
|
||||
probingIe->Init(aIeDataLength);
|
||||
|
||||
if (aIeData != nullptr)
|
||||
{
|
||||
aDest += sizeof(Mac::VendorIeHeader);
|
||||
memcpy(aDest, aIeData, aIeDataLength);
|
||||
probingIe->WriteMetricsDataFrom(aIeData);
|
||||
}
|
||||
|
||||
return sizeof(Mac::HeaderIe) + len;
|
||||
return probingIe->GetSize();
|
||||
}
|
||||
|
||||
void otMacFrameSetEnhAckProbingIe(otRadioFrame *aFrame, const uint8_t *aData, uint8_t aDataLen)
|
||||
{
|
||||
assert(aFrame != nullptr && aData != nullptr);
|
||||
|
||||
reinterpret_cast<Mac::Frame *>(aFrame)->SetEnhAckProbingIe(aData, aDataLen);
|
||||
reinterpret_cast<Mac::Frame *>(aFrame)->UpdateEnhAckProbingIe(aData, aDataLen);
|
||||
}
|
||||
#endif // OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
|
||||
|
||||
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
||||
static uint16_t ComputeCslPhase(uint32_t aRadioTime, otRadioContext *aRadioContext)
|
||||
{
|
||||
@@ -409,7 +404,7 @@ otError otMacFrameProcessTxSfd(otRadioFrame *aFrame, uint64_t aRadioTime, otRadi
|
||||
VerifyOrExit(!otMacFrameIsSecurityEnabled(aFrame) || !aFrame->mInfo.mTxInfo.mIsSecurityProcessed);
|
||||
|
||||
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
||||
if (static_cast<Mac::Frame *>(aFrame)->HasCslIe()) // CSL IE should be filled for every transmit attempt
|
||||
if (static_cast<Mac::Frame *>(aFrame)->Has<Mac::CslIe>()) // CSL IE should be filled for every transmit attempt
|
||||
{
|
||||
otMacFrameSetCslIe(aFrame, aRadioContext->mCslPeriod, ComputeCslPhase(aRadioTime, aRadioContext));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user