diff --git a/examples/platforms/utils/mac_frame.cpp b/examples/platforms/utils/mac_frame.cpp index c40e0b275..cde7a4f81 100644 --- a/examples/platforms/utils/mac_frame.cpp +++ b/examples/platforms/utils/mac_frame.cpp @@ -264,8 +264,7 @@ uint8_t otMacFrameGenerateCslIeTemplate(uint8_t *aDest) { assert(aDest != nullptr); - reinterpret_cast(aDest)->SetId(Mac::CslIe::kHeaderIeId); - reinterpret_cast(aDest)->SetLength(sizeof(Mac::CslIe)); + reinterpret_cast(aDest)->Init(Mac::CslIe::kHeaderIeId, sizeof(Mac::CslIe)); return sizeof(Mac::HeaderIe) + sizeof(Mac::CslIe); } @@ -278,8 +277,7 @@ uint8_t otMacFrameGenerateEnhAckProbingIe(uint8_t *aDest, const uint8_t *aIeData assert(aDest != nullptr); - reinterpret_cast(aDest)->SetId(Mac::ThreadIe::kHeaderIeId); - reinterpret_cast(aDest)->SetLength(len); + reinterpret_cast(aDest)->Init(Mac::ThreadIe::kHeaderIeId, len); aDest += sizeof(Mac::HeaderIe); diff --git a/src/core/mac/mac_frame.cpp b/src/core/mac/mac_frame.cpp index bf6739f61..f29536c9b 100644 --- a/src/core/mac/mac_frame.cpp +++ b/src/core/mac/mac_frame.cpp @@ -1081,12 +1081,13 @@ uint8_t Frame::FindPayloadIndex(void) const do { - const HeaderIe *ie = reinterpret_cast(&mPsdu[index]); + const HeaderIe *ie; - index += sizeof(HeaderIe); - VerifyOrExit(index + footerLength <= mLength, index = kInvalidIndex); + VerifyOrExit(index + footerLength + sizeof(HeaderIe) <= mLength, index = kInvalidIndex); + + ie = reinterpret_cast(&mPsdu[index]); + index += ie->GetSize(); - index += ie->GetLength(); VerifyOrExit(index + footerLength <= mLength, index = kInvalidIndex); if (ie->GetId() == Termination2Ie::kHeaderIeId) @@ -1173,7 +1174,7 @@ const uint8_t *Frame::GetHeaderIe(uint8_t aIeId) const ExitNow(); } - index += sizeof(HeaderIe) + ie->GetLength(); + index += ie->GetSize(); } exit: @@ -1198,8 +1199,8 @@ const uint8_t *Frame::GetThreadIe(uint8_t aSubType) const if ((ie->GetId() == VendorIeHeader::kHeaderIeId) && (ie->GetLength() >= VendorIeHeader::kIeContentSize)) { - const VendorIeHeader *vendorIe = - reinterpret_cast(reinterpret_cast(ie) + sizeof(HeaderIe)); + const VendorIeHeader *vendorIe = reinterpret_cast(ie->GetContent()); + if (vendorIe->GetVendorOui() == ThreadIe::kVendorOuiThreadCompanyId && vendorIe->GetSubType() == aSubType) { header = &mPsdu[index]; @@ -1207,7 +1208,7 @@ const uint8_t *Frame::GetThreadIe(uint8_t aSubType) const } } - index += sizeof(HeaderIe) + ie->GetLength(); + index += ie->GetSize(); } exit: @@ -1278,8 +1279,8 @@ const TimeIe *Frame::GetTimeIe(void) const if ((ie->GetId() == VendorIeHeader::kHeaderIeId) && (ie->GetLength() >= TimeIe::kIeContentSize)) { - const TimeIe *vendorIe = - reinterpret_cast(reinterpret_cast(ie) + sizeof(HeaderIe)); + const TimeIe *vendorIe = reinterpret_cast(ie->GetContent()); + if (vendorIe->GetVendorOui() == TimeIe::kVendorOuiNest && vendorIe->GetSubType() == TimeIe::kVendorIeTime) { timeIe = vendorIe; @@ -1287,7 +1288,7 @@ const TimeIe *Frame::GetTimeIe(void) const } } - index += sizeof(HeaderIe) + ie->GetLength(); + index += ie->GetSize(); } exit: diff --git a/src/core/mac/mac_header_ie.cpp b/src/core/mac/mac_header_ie.cpp index b6fb821f1..825c99fdc 100644 --- a/src/core/mac/mac_header_ie.cpp +++ b/src/core/mac/mac_header_ie.cpp @@ -36,11 +36,11 @@ namespace ot { namespace Mac { -void HeaderIe::Init(uint16_t aId, uint8_t aLen) +void HeaderIe::Init(uint8_t aId, uint8_t aLen) { - Init(); - SetId(aId); + mLenIdType = 0; SetLength(aLen); + SetId(aId); } #if OPENTHREAD_CONFIG_WAKEUP_COORDINATOR_ENABLE || OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE diff --git a/src/core/mac/mac_header_ie.hpp b/src/core/mac/mac_header_ie.hpp index e36234b2a..62332a963 100644 --- a/src/core/mac/mac_header_ie.hpp +++ b/src/core/mac/mac_header_ie.hpp @@ -38,6 +38,7 @@ #include "common/as_core_type.hpp" #include "common/bit_utils.hpp" +#include "common/const_cast.hpp" #include "common/encoding.hpp" #include "common/numeric_limits.hpp" #include "mac/mac_types.hpp" @@ -52,73 +53,73 @@ namespace Mac { */ /** - * Implements IEEE 802.15.4 IE (Information Element) header generation and parsing. + * Implements IEEE 802.15.4 IE (Information Element) generation and parsing. */ OT_TOOL_PACKED_BEGIN class HeaderIe { public: /** - * Initializes the Header IE. - */ - void Init(void) { mFields.m16 = 0; } - - /** - * Initializes the Header IE with Id and Length. + * Initializes the Header IE with a given ID and Length. * - * @param[in] aId The IE Element Id. + * @param[in] aId The IE Element ID. * @param[in] aLen The IE content length. */ - void Init(uint16_t aId, uint8_t aLen); + void Init(uint8_t aId, uint8_t aLen); /** - * Returns the IE Element Id. + * Returns the IE Element ID. * - * @returns the IE Element Id. + * @returns the IE Element ID. */ - uint16_t GetId(void) const { return ReadBitsLittleEndian(mFields.m16); } - - /** - * Sets the IE Element Id. - * - * @param[in] aId The IE Element Id. - */ - void SetId(uint16_t aId) { mFields.m16 = UpdateBitsLittleEndian(mFields.m16, aId); } + uint8_t GetId(void) const { return static_cast(ReadBitsLittleEndian(mLenIdType)); } /** * Returns the IE content length. * * @returns the IE content length. */ - uint8_t GetLength(void) const { return ReadBits(mFields.m8[0]); } + uint8_t GetLength(void) const { return static_cast(ReadBitsLittleEndian(mLenIdType)); } /** - * Sets the IE content length. + * Returns the total size of the Header IE (descriptor header plus content length) in bytes. * - * @param[in] aLength The IE content length. + * @note The total size fits in a `uint8_t` since the content length is limited to 7 bits (max 127 bytes). + * + * @returns The total size of the Header IE in bytes. */ - void SetLength(uint8_t aLength) { WriteBits(mFields.m8[0], aLength); } + uint8_t GetSize(void) const { return GetLength() + sizeof(HeaderIe); } + + /** + * Returns a pointer to the IE content bytes. + * + * @returns A pointer to the IE content bytes. + */ + const uint8_t *GetContent(void) const { return GetBytes() + sizeof(HeaderIe); } + + /** + * Returns a pointer to the IE content bytes. + * + * @returns A pointer to the IE content bytes. + */ + uint8_t *GetContent(void) { return AsNonConst(AsConst(this)->GetContent()); } private: - // Header IE format: + // IEEE 802.15.4 Header IE descriptor (2 bytes, little-endian): // - // +-----------+------------+--------+ - // | Bits: 0-6 | 7-14 | 15 | - // +-----------+------------+--------+ - // | Length | Element ID | Type=0 | - // +-----------+------------+--------+ + // Bits 0-6 (7 bits) : Length of IE content in bytes (max 127). + // Bits 7-14 (8 bits) : Element ID. + // Bit 15 (1 bit) : Type (0 for Header IE). - static constexpr uint8_t kSize = 2; - static constexpr uint8_t kIdOffset = 7; - static constexpr uint8_t kLengthMask = 0x7f; - static constexpr uint16_t kIdMask = 0x00ff << kIdOffset; + static constexpr uint16_t kLenMask = 0x007f << 0; + static constexpr uint16_t kIdMask = 0x00ff << 7; - union OT_TOOL_PACKED_FIELD - { - uint8_t m8[kSize]; - uint16_t m16; - } mFields; + void SetId(uint8_t aId) { mLenIdType = UpdateBitsLittleEndian(mLenIdType, aId); } + void SetLength(uint8_t aLength) { mLenIdType = UpdateBitsLittleEndian(mLenIdType, aLength); } + const uint8_t *GetBytes(void) const { return reinterpret_cast(this); } + + uint16_t mLenIdType; } OT_TOOL_PACKED_END; /**