[mac-frame] add TxFrame::Info and simplify mac header preparation (#10689)

This commit simplifies the preparation of MAC and security frames. It
introduces a `TxFrame::Info` structure that provides information
about the frame, such as its type, version, source and destination
addresses, PAN IDs, security level, and key ID mode. A new method
`PrepareHeadersIn()` is added, which uses the `Info` structure to
construct the MAC address and security headers in a given `TxFrame`.

This approach replaces the earlier `Mac::Frame::InitMacHeader()` where
all the information was passed as a list of input arguments. The
`TxFrame::Info` approach simplifies the code and allows for future
extension to accommodate other parameters (e.g., Header IE entries).
This commit is contained in:
Abtin Keshavarzian
2024-10-01 11:37:17 -07:00
committed by GitHub
parent 3a28b7bbdf
commit 09698fae24
10 changed files with 245 additions and 185 deletions
+14 -2
View File
@@ -45,11 +45,11 @@
namespace ot {
void FrameBuilder::Init(void *aBuffer, uint16_t aLength)
void FrameBuilder::Init(void *aBuffer, uint16_t aMaxLength)
{
mBuffer = static_cast<uint8_t *>(aBuffer);
mLength = 0;
mMaxLength = aLength;
mMaxLength = aMaxLength;
}
Error FrameBuilder::AppendUint8(uint8_t aUint8) { return Append<uint8_t>(aUint8); }
@@ -118,6 +118,18 @@ exit:
}
#endif
void *FrameBuilder::AppendLength(uint16_t aLength)
{
void *buffer = nullptr;
VerifyOrExit(CanAppend(aLength));
buffer = &mBuffer[mLength];
mLength += aLength;
exit:
return buffer;
}
void FrameBuilder::WriteBytes(uint16_t aOffset, const void *aBuffer, uint16_t aLength)
{
memcpy(mBuffer + aOffset, aBuffer, aLength);
+34 -2
View File
@@ -55,9 +55,9 @@ public:
* `FrameBuilder` MUST be initialized before its other methods are used.
*
* @param[in] aBuffer A pointer to a buffer.
* @param[in] aLength The data length (number of bytes in @p aBuffer).
* @param[in] aLength The max data length (number of bytes in @p aBuffer).
*/
void Init(void *aBuffer, uint16_t aLength);
void Init(void *aBuffer, uint16_t aMaxLength);
/**
* Returns a pointer to the start of `FrameBuilder` buffer.
@@ -211,6 +211,38 @@ public:
return AppendBytes(&aObject, sizeof(ObjectType));
}
/**
* Appends the given number of bytes to the `FrameBuilder`.
*
* This method reserves @p aLength bytes at the current position of the `FrameBuilder` and returns a pointer to the
* start of this reserved buffer if successful. The reserved bytes are left uninitialized. The caller is
* responsible for initializing them.
*
* @param[in] aLength The number of bytes to append.
*
* @returns A pointer to the start of the appended bytes if successful, or `nullptr` if there are not enough
* remaining bytes to append @p aLength bytes.
*/
void *AppendLength(uint16_t aLength);
/**
* Appends an object to the `FrameBuilder`.
*
* @tparam ObjectType The object type to append.
*
* This method reserves bytes in `FrameBuilder` to accommodate an `ObjectType` and returns a pointer to the
* appended `ObjectType`. The `ObjectType` bytes are left uninitialized. Caller is responsible to initialize them.
*
* @returns A pointer the appended `ObjectType` if successful, or `nullptr` if there are not enough remaining
* bytes to append an `ObjectType`.
*/
template <typename ObjectType> ObjectType *Append(void)
{
static_assert(!TypeTraits::IsPointer<ObjectType>::kValue, "ObjectType must not be a pointer");
return static_cast<ObjectType *>(AppendLength(sizeof(ObjectType)));
}
/**
* Writes bytes in `FrameBuilder` at a given offset overwriting the previously appended content.
*
+13 -11
View File
@@ -542,33 +542,35 @@ uint32_t DataPollSender::GetDefaultPollPeriod(void) const
Mac::TxFrame *DataPollSender::PrepareDataRequest(Mac::TxFrames &aTxFrames)
{
Mac::TxFrame *frame = nullptr;
Mac::Addresses addresses;
Mac::PanIds panIds;
Mac::TxFrame *frame = nullptr;
Mac::TxFrame::Info frameInfo;
#if OPENTHREAD_CONFIG_MULTI_RADIO
Mac::RadioType radio;
SuccessOrExit(GetPollDestinationAddress(addresses.mDestination, radio));
SuccessOrExit(GetPollDestinationAddress(frameInfo.mAddrs.mDestination, radio));
frame = &aTxFrames.GetTxFrame(radio);
#else
SuccessOrExit(GetPollDestinationAddress(addresses.mDestination));
SuccessOrExit(GetPollDestinationAddress(frameInfo.mAddrs.mDestination));
frame = &aTxFrames.GetTxFrame();
#endif
if (addresses.mDestination.IsExtended())
if (frameInfo.mAddrs.mDestination.IsExtended())
{
addresses.mSource.SetExtended(Get<Mac::Mac>().GetExtAddress());
frameInfo.mAddrs.mSource.SetExtended(Get<Mac::Mac>().GetExtAddress());
}
else
{
addresses.mSource.SetShort(Get<Mac::Mac>().GetShortAddress());
frameInfo.mAddrs.mSource.SetShort(Get<Mac::Mac>().GetShortAddress());
}
panIds.SetBothSourceDestination(Get<Mac::Mac>().GetPanId());
frameInfo.mPanIds.SetBothSourceDestination(Get<Mac::Mac>().GetPanId());
Get<MeshForwarder>().PrepareMacHeaders(*frame, Mac::Frame::kTypeMacCmd, addresses, panIds,
Mac::Frame::kSecurityEncMic32, Mac::Frame::kKeyIdMode1, nullptr);
frameInfo.mType = Mac::Frame::kTypeMacCmd;
frameInfo.mSecurityLevel = Mac::Frame::kSecurityEncMic32;
frameInfo.mKeyIdMode = Mac::Frame::kKeyIdMode1;
Get<MeshForwarder>().PrepareMacHeaders(*frame, frameInfo, nullptr);
#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT && OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
if (frame->HasCslIe())
+19 -15
View File
@@ -722,15 +722,17 @@ void Mac::FinishOperation(void)
TxFrame *Mac::PrepareBeaconRequest(void)
{
TxFrame &frame = mLinks.GetTxFrames().GetBroadcastTxFrame();
Addresses addrs;
PanIds panIds;
TxFrame &frame = mLinks.GetTxFrames().GetBroadcastTxFrame();
TxFrame::Info frameInfo;
addrs.mSource.SetNone();
addrs.mDestination.SetShort(kShortAddrBroadcast);
panIds.SetDestination(kShortAddrBroadcast);
frameInfo.mAddrs.mSource.SetNone();
frameInfo.mAddrs.mDestination.SetShort(kShortAddrBroadcast);
frameInfo.mPanIds.SetDestination(kShortAddrBroadcast);
frame.InitMacHeader(Frame::kTypeMacCmd, Frame::kVersion2003, addrs, panIds, Frame::kSecurityNone);
frameInfo.mType = Frame::kTypeMacCmd;
frameInfo.mVersion = Frame::kVersion2003;
frameInfo.PrepareHeadersIn(frame);
IgnoreError(frame.SetCommandId(Frame::kMacCmdBeaconRequest));
@@ -741,10 +743,9 @@ TxFrame *Mac::PrepareBeaconRequest(void)
TxFrame *Mac::PrepareBeacon(void)
{
TxFrame *frame;
Beacon *beacon = nullptr;
Addresses addrs;
PanIds panIds;
TxFrame *frame;
TxFrame::Info frameInfo;
Beacon *beacon = nullptr;
#if OPENTHREAD_CONFIG_MAC_OUTGOING_BEACON_PAYLOAD_ENABLE
uint8_t beaconLength;
BeaconPayload *beaconPayload = nullptr;
@@ -758,11 +759,14 @@ TxFrame *Mac::PrepareBeacon(void)
frame = &mLinks.GetTxFrames().GetBroadcastTxFrame();
#endif
addrs.mSource.SetExtended(GetExtAddress());
panIds.SetSource(mPanId);
addrs.mDestination.SetNone();
frameInfo.mAddrs.mSource.SetExtended(GetExtAddress());
frameInfo.mPanIds.SetSource(mPanId);
frameInfo.mAddrs.mDestination.SetNone();
frame->InitMacHeader(Frame::kTypeBeacon, Frame::kVersion2003, addrs, panIds, Frame::kSecurityNone);
frameInfo.mType = Frame::kTypeBeacon;
frameInfo.mVersion = Frame::kVersion2003;
frameInfo.PrepareHeadersIn(*frame);
beacon = reinterpret_cast<Beacon *>(frame->GetPayload());
beacon->Init();
+53 -53
View File
@@ -48,20 +48,15 @@
namespace ot {
namespace Mac {
void Frame::InitMacHeader(Type aType,
Version aVersion,
const Addresses &aAddrs,
const PanIds &aPanIds,
SecurityLevel aSecurityLevel,
KeyIdMode aKeyIdMode,
bool aSuppressSequence)
void TxFrame::Info::PrepareHeadersIn(TxFrame &aTxFrame) const
{
uint16_t fcf;
FrameBuilder builder;
uint8_t micSize = 0;
fcf = static_cast<uint16_t>(aType) | static_cast<uint16_t>(aVersion);
fcf = static_cast<uint16_t>(mType) | static_cast<uint16_t>(mVersion);
switch (aAddrs.mSource.GetType())
switch (mAddrs.mSource.GetType())
{
case Address::kTypeNone:
fcf |= kFcfSrcAddrNone;
@@ -74,30 +69,30 @@ void Frame::InitMacHeader(Type aType,
break;
}
switch (aAddrs.mDestination.GetType())
switch (mAddrs.mDestination.GetType())
{
case Address::kTypeNone:
fcf |= kFcfDstAddrNone;
break;
case Address::kTypeShort:
fcf |= kFcfDstAddrShort;
fcf |= ((aAddrs.mDestination.GetShort() == kShortAddrBroadcast) ? 0 : kFcfAckRequest);
fcf |= ((mAddrs.mDestination.GetShort() == kShortAddrBroadcast) ? 0 : kFcfAckRequest);
break;
case Address::kTypeExtended:
fcf |= (kFcfDstAddrExt | kFcfAckRequest);
break;
}
if (aType == kTypeAck)
if (mType == kTypeAck)
{
fcf &= ~kFcfAckRequest;
}
fcf |= (aSecurityLevel != kSecurityNone) ? kFcfSecurityEnabled : 0;
fcf |= (mSecurityLevel != kSecurityNone) ? kFcfSecurityEnabled : 0;
// PAN ID compression
switch (aVersion)
switch (mVersion)
{
case kVersion2003:
case kVersion2006:
@@ -114,14 +109,14 @@ void Frame::InitMacHeader(Type aType,
// PAN ID Compression field shall be set to zero, and both Destination PAN ID
// field and Source PAN ID fields shall be included in the transmitted frame.
if (!aAddrs.mSource.IsNone() && !aAddrs.mDestination.IsNone() &&
(aPanIds.GetSource() == aPanIds.GetDestination()))
if (!mAddrs.mSource.IsNone() && !mAddrs.mDestination.IsNone() &&
(mPanIds.GetSource() == mPanIds.GetDestination()))
{
fcf |= kFcfPanidCompression;
}
// Sequence Number Suppression bit was reserved, and must not be set on initialization.
OT_ASSERT(!aSuppressSequence);
OT_ASSERT(!mSuppressSequence);
break;
case kVersion2015:
@@ -146,12 +141,12 @@ void Frame::InitMacHeader(Type aType,
// | 14 | Short | Short | Present | Not Present | 1 |
// +----+--------------+--------------+--------------+--------------+--------------+
if (aAddrs.mDestination.IsNone())
if (mAddrs.mDestination.IsNone())
{
// Dst addr not present - rows 1,2,5,6.
if ((aAddrs.mSource.IsNone() && aPanIds.IsDestinationPresent()) || // Row 2.
(!aAddrs.mSource.IsNone() && !aPanIds.IsDestinationPresent() && !aPanIds.IsSourcePresent())) // Row 6.
if ((mAddrs.mSource.IsNone() && mPanIds.IsDestinationPresent()) || // Row 2.
(!mAddrs.mSource.IsNone() && !mPanIds.IsDestinationPresent() && !mPanIds.IsSourcePresent())) // Row 6.
{
fcf |= kFcfPanidCompression;
}
@@ -159,11 +154,11 @@ void Frame::InitMacHeader(Type aType,
break;
}
if (aAddrs.mSource.IsNone())
if (mAddrs.mSource.IsNone())
{
// Dst addr present, Src addr not present - rows 3,4.
if (!aPanIds.IsDestinationPresent()) // Row 4.
if (!mPanIds.IsDestinationPresent()) // Row 4.
{
fcf |= kFcfPanidCompression;
}
@@ -173,16 +168,16 @@ void Frame::InitMacHeader(Type aType,
// Both addresses are present - rows 7 to 14.
if (aAddrs.mSource.IsExtended() && aAddrs.mDestination.IsExtended())
if (mAddrs.mSource.IsExtended() && mAddrs.mDestination.IsExtended())
{
// Both addresses are extended - rows 7,8.
if (aPanIds.IsDestinationPresent()) // Row 7.
if (mPanIds.IsDestinationPresent()) // Row 7.
{
break;
}
}
else if (aPanIds.GetSource() != aPanIds.GetDestination()) // Rows 9-14.
else if (mPanIds.GetSource() != mPanIds.GetDestination()) // Rows 9-14.
{
break;
}
@@ -192,51 +187,53 @@ void Frame::InitMacHeader(Type aType,
break;
}
if (aSuppressSequence)
if (mSuppressSequence)
{
fcf |= kFcfSequenceSuppression;
}
builder.Init(mPsdu, GetMtu());
builder.Init(aTxFrame.mPsdu, aTxFrame.GetMtu());
IgnoreError(builder.AppendLittleEndianUint16(fcf));
if (IsSequencePresent(fcf))
{
IgnoreError(builder.AppendUint8(0)); // Seq number
builder.Append<uint8_t>(); // Place holder for seq number
}
if (IsDstPanIdPresent(fcf))
{
IgnoreError(builder.AppendLittleEndianUint16(aPanIds.GetDestination()));
IgnoreError(builder.AppendLittleEndianUint16(mPanIds.GetDestination()));
}
IgnoreError(builder.AppendMacAddress(aAddrs.mDestination));
IgnoreError(builder.AppendMacAddress(mAddrs.mDestination));
if (IsSrcPanIdPresent(fcf))
{
IgnoreError(builder.AppendLittleEndianUint16(aPanIds.GetSource()));
IgnoreError(builder.AppendLittleEndianUint16(mPanIds.GetSource()));
}
IgnoreError(builder.AppendMacAddress(aAddrs.mSource));
IgnoreError(builder.AppendMacAddress(mAddrs.mSource));
mLength = builder.GetLength();
aTxFrame.mLength = builder.GetLength();
if (aSecurityLevel != kSecurityNone)
if (mSecurityLevel != kSecurityNone)
{
uint8_t secCtl = static_cast<uint8_t>(aSecurityLevel) | static_cast<uint8_t>(aKeyIdMode);
uint8_t secCtl = static_cast<uint8_t>(mSecurityLevel) | static_cast<uint8_t>(mKeyIdMode);
IgnoreError(builder.AppendUint8(secCtl));
builder.AppendLength(CalculateSecurityHeaderSize(secCtl) - sizeof(secCtl));
mLength += CalculateSecurityHeaderSize(secCtl);
mLength += CalculateMicSize(secCtl);
micSize = CalculateMicSize(secCtl);
}
if (aType == kTypeMacCmd)
if (mType == kTypeMacCmd)
{
mLength += kCommandIdSize;
builder.Append<uint8_t>(); // Placeholder for Command ID
}
mLength += GetFcsSize();
builder.AppendLength(micSize + aTxFrame.GetFcsSize());
aTxFrame.mLength = builder.GetLength();
}
void Frame::SetFrameControlField(uint16_t aFcf)
@@ -1546,13 +1543,12 @@ void TxFrame::GenerateImmAck(const RxFrame &aFrame, bool aIsFramePending)
#if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
Error TxFrame::GenerateEnhAck(const RxFrame &aRxFrame, bool aIsFramePending, const uint8_t *aIeData, uint8_t aIeLength)
{
Error error = kErrorNone;
Address address;
PanId panId;
Addresses addrs;
PanIds panIds;
uint8_t securityLevel = kSecurityNone;
uint8_t keyIdMode = kKeyIdMode0;
Error error = kErrorNone;
Info frameInfo;
Address address;
PanId panId;
uint8_t securityLevel = kSecurityNone;
uint8_t keyIdMode = kKeyIdMode0;
// Validate the received frame.
@@ -1569,8 +1565,8 @@ Error TxFrame::GenerateEnhAck(const RxFrame &aRxFrame, bool aIsFramePending, con
// Check `aRxFrame` has a valid source, which is then used as
// ack frames destination.
SuccessOrExit(error = aRxFrame.GetSrcAddr(addrs.mDestination));
VerifyOrExit(!addrs.mDestination.IsNone(), error = kErrorParse);
SuccessOrExit(error = aRxFrame.GetSrcAddr(frameInfo.mAddrs.mDestination));
VerifyOrExit(!frameInfo.mAddrs.mDestination.IsNone(), error = kErrorParse);
if (aRxFrame.GetSecurityEnabled())
{
@@ -1583,12 +1579,12 @@ Error TxFrame::GenerateEnhAck(const RxFrame &aRxFrame, bool aIsFramePending, con
if (aRxFrame.IsSrcPanIdPresent())
{
SuccessOrExit(error = aRxFrame.GetSrcPanId(panId));
panIds.SetDestination(panId);
frameInfo.mPanIds.SetDestination(panId);
}
else if (aRxFrame.IsDstPanIdPresent())
{
SuccessOrExit(error = aRxFrame.GetDstPanId(panId));
panIds.SetDestination(panId);
frameInfo.mPanIds.SetDestination(panId);
}
// Prepare the ack frame
@@ -1596,8 +1592,12 @@ Error TxFrame::GenerateEnhAck(const RxFrame &aRxFrame, bool aIsFramePending, con
mChannel = aRxFrame.mChannel;
ClearAllBytes(mInfo.mTxInfo);
InitMacHeader(kTypeAck, kVersion2015, addrs, panIds, static_cast<SecurityLevel>(securityLevel),
static_cast<KeyIdMode>(keyIdMode));
frameInfo.mType = kTypeAck;
frameInfo.mVersion = kVersion2015;
frameInfo.mSecurityLevel = static_cast<SecurityLevel>(securityLevel);
frameInfo.mKeyIdMode = static_cast<KeyIdMode>(keyIdMode);
frameInfo.PrepareHeadersIn(*this);
SetFramePending(aIsFramePending);
SetIePresent(aIeLength != 0);
+39 -25
View File
@@ -155,31 +155,6 @@ public:
*/
bool IsEmpty(void) const { return (mLength == 0); }
/**
* Initializes the MAC header.
*
* Determines and writes the Frame Control Field (FCF) and Security Control in the frame along with
* given source and destination addresses and PAN IDs.
*
* The Ack Request bit in FCF is set if there is destination and it is not broadcast and frame type @p aType is not
* ACK. The Frame Pending and IE Present bits are not set.
*
* @param[in] aType Frame type.
* @param[in] aVersion Frame version.
* @param[in] aAddrs Frame source and destination addresses (each can be none, short, or extended).
* @param[in] aPanIds Source and destination PAN IDs.
* @param[in] aSecurityLevel Frame security level.
* @param[in] aKeyIdMode Frame security key ID mode.
* @param[in] aSuppressSequence Whether to suppress sequence number.
*/
void InitMacHeader(Type aType,
Version aVersion,
const Addresses &aAddrs,
const PanIds &aPanIds,
SecurityLevel aSecurityLevel,
KeyIdMode aKeyIdMode = kKeyIdMode0,
bool aSuppressSequence = false);
/**
* Validates the frame.
*
@@ -1136,6 +1111,45 @@ public:
class TxFrame : public Frame
{
public:
/**
* Represents header information.
*/
struct Info : public Clearable<Info>
{
/**
* Initializes the `Info` by clearing all its fields (setting all bytes to zero).
*/
Info(void) { Clear(); }
/**
* Prepares MAC headers based on `Info` fields in a given `TxFrame`.
*
* This method uses the `Info` structure to construct the MAC address and security headers in @p aTxFrame.
* It determines the Frame Control Field (FCF), including setting the appropriate frame type, security level,
* and addressing mode flags. It populates the source and destination addresses and PAN IDs within the MAC
* header based on the information provided in the `Info` structure.
*
* It sets the Ack Request bit in the FCF if the following criteria are met:
* - A destination address is present
* - The destination address is not the broadcast address
* - The frame type is not an ACK frame
*
* The Frame Pending and IE Present flags in the FCF are not set. They may need to be set separately depending
* on the specific requirements of the frame being transmitted.
*
* @param[in,out] aTxFrame The `TxFrame` instance in which to prepare and append the MAC headers.
*/
void PrepareHeadersIn(TxFrame &aTxFrame) const;
Type mType; ///< Frame type.
Version mVersion; ///< Frame version.
Addresses mAddrs; ///< Frame source and destination addresses.
PanIds mPanIds; ///< Source and destination PAN Ids.
SecurityLevel mSecurityLevel; ///< Frame security level.
KeyIdMode mKeyIdMode; ///< Frame security key ID mode.
bool mSuppressSequence : 1; ///< Whether to suppress seq number.
};
/**
* Sets the channel on which to send the frame.
*
+34 -39
View File
@@ -162,21 +162,23 @@ exit:
void MeshForwarder::PrepareEmptyFrame(Mac::TxFrame &aFrame, const Mac::Address &aMacDest, bool aAckRequest)
{
Mac::Addresses addresses;
Mac::PanIds panIds;
Mac::TxFrame::Info frameInfo;
addresses.mSource.SetShort(Get<Mac::Mac>().GetShortAddress());
frameInfo.mAddrs.mSource.SetShort(Get<Mac::Mac>().GetShortAddress());
if (addresses.mSource.IsShortAddrInvalid() || aMacDest.IsExtended())
if (frameInfo.mAddrs.mSource.IsShortAddrInvalid() || aMacDest.IsExtended())
{
addresses.mSource.SetExtended(Get<Mac::Mac>().GetExtAddress());
frameInfo.mAddrs.mSource.SetExtended(Get<Mac::Mac>().GetExtAddress());
}
addresses.mDestination = aMacDest;
panIds.SetBothSourceDestination(Get<Mac::Mac>().GetPanId());
frameInfo.mAddrs.mDestination = aMacDest;
frameInfo.mPanIds.SetBothSourceDestination(Get<Mac::Mac>().GetPanId());
PrepareMacHeaders(aFrame, Mac::Frame::kTypeData, addresses, panIds, Mac::Frame::kSecurityEncMic32,
Mac::Frame::kKeyIdMode1, nullptr);
frameInfo.mType = Mac::Frame::kTypeData;
frameInfo.mSecurityLevel = Mac::Frame::kSecurityEncMic32;
frameInfo.mKeyIdMode = Mac::Frame::kKeyIdMode1;
PrepareMacHeaders(aFrame, frameInfo, nullptr);
aFrame.SetAckRequest(aAckRequest);
aFrame.SetPayloadLength(0);
@@ -836,26 +838,20 @@ exit:
return frame;
}
void MeshForwarder::PrepareMacHeaders(Mac::TxFrame &aFrame,
Mac::Frame::Type aFrameType,
const Mac::Addresses &aMacAddrs,
const Mac::PanIds &aPanIds,
Mac::Frame::SecurityLevel aSecurityLevel,
Mac::Frame::KeyIdMode aKeyIdMode,
const Message *aMessage)
void MeshForwarder::PrepareMacHeaders(Mac::TxFrame &aTxFrame, Mac::TxFrame::Info &aTxFrameInfo, const Message *aMessage)
{
bool iePresent;
Mac::Frame::Version version;
bool iePresent;
iePresent = CalcIePresent(aMessage);
version = CalcFrameVersion(Get<NeighborTable>().FindNeighbor(aMacAddrs.mDestination), iePresent);
aTxFrameInfo.mVersion =
CalcFrameVersion(Get<NeighborTable>().FindNeighbor(aTxFrameInfo.mAddrs.mDestination), iePresent);
aFrame.InitMacHeader(aFrameType, version, aMacAddrs, aPanIds, aSecurityLevel, aKeyIdMode);
aTxFrameInfo.PrepareHeadersIn(aTxFrame);
#if OPENTHREAD_CONFIG_MAC_HEADER_IE_SUPPORT
if (iePresent)
{
AppendHeaderIe(aMessage, aFrame);
AppendHeaderIe(aMessage, aTxFrame);
}
#endif
}
@@ -879,59 +875,58 @@ uint16_t MeshForwarder::PrepareDataFrame(Mac::TxFrame &aFrame,
uint16_t aMeshDest,
bool aAddFragHeader)
{
Mac::Frame::SecurityLevel securityLevel;
Mac::Frame::KeyIdMode keyIdMode;
Mac::PanIds panIds;
uint16_t payloadLength;
uint16_t origMsgOffset;
uint16_t nextOffset;
FrameBuilder frameBuilder;
Mac::TxFrame::Info frameInfo;
uint16_t payloadLength;
uint16_t origMsgOffset;
uint16_t nextOffset;
FrameBuilder frameBuilder;
start:
securityLevel = Mac::Frame::kSecurityNone;
keyIdMode = Mac::Frame::kKeyIdMode1;
frameInfo.Clear();
if (aMessage.IsLinkSecurityEnabled())
{
securityLevel = Mac::Frame::kSecurityEncMic32;
frameInfo.mSecurityLevel = Mac::Frame::kSecurityEncMic32;
switch (aMessage.GetSubType())
{
case Message::kSubTypeJoinerEntrust:
keyIdMode = Mac::Frame::kKeyIdMode0;
frameInfo.mKeyIdMode = Mac::Frame::kKeyIdMode0;
break;
case Message::kSubTypeMleAnnounce:
keyIdMode = Mac::Frame::kKeyIdMode2;
frameInfo.mKeyIdMode = Mac::Frame::kKeyIdMode2;
break;
default:
// Use the `kKeyIdMode1`
frameInfo.mKeyIdMode = Mac::Frame::kKeyIdMode1;
break;
}
}
panIds.SetBothSourceDestination(Get<Mac::Mac>().GetPanId());
frameInfo.mPanIds.SetBothSourceDestination(Get<Mac::Mac>().GetPanId());
switch (aMessage.GetSubType())
{
case Message::kSubTypeMleAnnounce:
aFrame.SetChannel(aMessage.GetChannel());
aFrame.SetRxChannelAfterTxDone(Get<Mac::Mac>().GetPanChannel());
panIds.SetDestination(Mac::kPanIdBroadcast);
frameInfo.mPanIds.SetDestination(Mac::kPanIdBroadcast);
break;
case Message::kSubTypeMleDiscoverRequest:
case Message::kSubTypeMleDiscoverResponse:
panIds.SetDestination(aMessage.GetPanId());
frameInfo.mPanIds.SetDestination(aMessage.GetPanId());
break;
default:
break;
}
PrepareMacHeaders(aFrame, Mac::Frame::kTypeData, aMacAddrs, panIds, securityLevel, keyIdMode, &aMessage);
frameInfo.mType = Mac::Frame::kTypeData;
frameInfo.mAddrs = aMacAddrs;
PrepareMacHeaders(aFrame, frameInfo, &aMessage);
frameBuilder.Init(aFrame.GetPayload(), aFrame.GetMaxPayloadLength());
+1 -7
View File
@@ -509,13 +509,7 @@ private:
void HandleFragment(RxInfo &aRxInfo);
void HandleLowpanHc(RxInfo &aRxInfo);
void PrepareMacHeaders(Mac::TxFrame &aFrame,
Mac::Frame::Type aFrameType,
const Mac::Addresses &aMacAddr,
const Mac::PanIds &aPanIds,
Mac::Frame::SecurityLevel aSecurityLevel,
Mac::Frame::KeyIdMode aKeyIdMode,
const Message *aMessage);
void PrepareMacHeaders(Mac::TxFrame &aTxFrame, Mac::TxFrame::Info &aTxFrameInfo, const Message *aMessage);
uint16_t PrepareDataFrame(Mac::TxFrame &aFrame,
Message &aMessage,
const Mac::Addresses &aMacAddrs,
+7 -4
View File
@@ -328,12 +328,15 @@ void MeshForwarder::RemoveDataResponseMessages(void)
void MeshForwarder::SendMesh(Message &aMessage, Mac::TxFrame &aFrame)
{
Mac::PanIds panIds;
Mac::TxFrame::Info frameInfo;
panIds.SetBothSourceDestination(Get<Mac::Mac>().GetPanId());
frameInfo.mType = Mac::Frame::kTypeData;
frameInfo.mAddrs = mMacAddrs;
frameInfo.mSecurityLevel = Mac::Frame::kSecurityEncMic32;
frameInfo.mKeyIdMode = Mac::Frame::kKeyIdMode1;
frameInfo.mPanIds.SetBothSourceDestination(Get<Mac::Mac>().GetPanId());
PrepareMacHeaders(aFrame, Mac::Frame::kTypeData, mMacAddrs, panIds, Mac::Frame::kSecurityEncMic32,
Mac::Frame::kKeyIdMode1, &aMessage);
PrepareMacHeaders(aFrame, frameInfo, &aMessage);
// write payload
OT_ASSERT(aMessage.GetLength() <= aFrame.GetMaxPayloadLength());
+31 -27
View File
@@ -290,44 +290,43 @@ void TestMacHeader(void)
uint8_t psdu[OT_RADIO_FRAME_MAX_SIZE];
uint8_t offset;
Mac::TxFrame frame;
Mac::Addresses addresses;
Mac::Address address;
Mac::PanIds panIds;
Mac::PanId panId;
Mac::TxFrame frame;
Mac::TxFrame::Info frameInfo;
Mac::Address address;
Mac::PanId panId;
frame.mPsdu = psdu;
frame.mLength = 0;
frame.mRadioType = 0;
VerifyOrQuit(addresses.mSource.IsNone());
VerifyOrQuit(addresses.mDestination.IsNone());
VerifyOrQuit(!panIds.IsSourcePresent());
VerifyOrQuit(!panIds.IsDestinationPresent());
VerifyOrQuit(frameInfo.mAddrs.mSource.IsNone());
VerifyOrQuit(frameInfo.mAddrs.mDestination.IsNone());
VerifyOrQuit(!frameInfo.mPanIds.IsSourcePresent());
VerifyOrQuit(!frameInfo.mPanIds.IsDestinationPresent());
switch (testCase.mSrcAddrType)
{
case kNoneAddr:
addresses.mSource.SetNone();
frameInfo.mAddrs.mSource.SetNone();
break;
case kShrtAddr:
addresses.mSource.SetShort(kShortAddr1);
frameInfo.mAddrs.mSource.SetShort(kShortAddr1);
break;
case kExtdAddr:
addresses.mSource.SetExtended(extAddr1);
frameInfo.mAddrs.mSource.SetExtended(extAddr1);
break;
}
switch (testCase.mDstAddrType)
{
case kNoneAddr:
addresses.mDestination.SetNone();
frameInfo.mAddrs.mDestination.SetNone();
break;
case kShrtAddr:
addresses.mDestination.SetShort(kShortAddr2);
frameInfo.mAddrs.mDestination.SetShort(kShortAddr2);
break;
case kExtdAddr:
addresses.mDestination.SetExtended(extAddr2);
frameInfo.mAddrs.mDestination.SetExtended(extAddr2);
break;
}
@@ -336,10 +335,10 @@ void TestMacHeader(void)
case kNoPanId:
break;
case kUsePanId1:
panIds.SetSource(kPanId1);
frameInfo.mPanIds.SetSource(kPanId1);
break;
case kUsePanId2:
panIds.SetSource(kPanId2);
frameInfo.mPanIds.SetSource(kPanId2);
break;
}
@@ -348,15 +347,20 @@ void TestMacHeader(void)
case kNoPanId:
break;
case kUsePanId1:
panIds.SetDestination(kPanId1);
frameInfo.mPanIds.SetDestination(kPanId1);
break;
case kUsePanId2:
panIds.SetDestination(kPanId2);
frameInfo.mPanIds.SetDestination(kPanId2);
break;
}
frame.InitMacHeader(Mac::Frame::kTypeData, testCase.mVersion, addresses, panIds, testCase.mSecurity,
testCase.mKeyIdMode, testCase.mSuppressSequence);
frameInfo.mType = Mac::Frame::kTypeData;
frameInfo.mVersion = testCase.mVersion;
frameInfo.mSecurityLevel = testCase.mSecurity;
frameInfo.mKeyIdMode = testCase.mKeyIdMode;
frameInfo.mSuppressSequence = testCase.mSuppressSequence;
frameInfo.PrepareHeadersIn(frame);
VerifyOrQuit(frame.GetHeaderLength() == testCase.mHeaderLength);
VerifyOrQuit(frame.GetFooterLength() == testCase.mFooterLength);
@@ -372,25 +376,25 @@ void TestMacHeader(void)
VerifyOrQuit(frame.IsSrcAddrPresent() == (testCase.mSrcAddrType != kNoneAddr));
SuccessOrQuit(frame.GetSrcAddr(address));
VerifyOrQuit(CompareAddresses(address, addresses.mSource));
VerifyOrQuit(CompareAddresses(address, frameInfo.mAddrs.mSource));
VerifyOrQuit(frame.IsDstAddrPresent() == (testCase.mDstAddrType != kNoneAddr));
SuccessOrQuit(frame.GetDstAddr(address));
VerifyOrQuit(CompareAddresses(address, addresses.mDestination));
VerifyOrQuit(CompareAddresses(address, frameInfo.mAddrs.mDestination));
VerifyOrQuit(frame.IsDstPanIdPresent() == (testCase.mDstPanIdMode != kNoPanId));
if (frame.IsDstPanIdPresent())
{
SuccessOrQuit(frame.GetDstPanId(panId));
VerifyOrQuit(panId == panIds.GetDestination());
VerifyOrQuit(panIds.IsDestinationPresent());
VerifyOrQuit(panId == frameInfo.mPanIds.GetDestination());
VerifyOrQuit(frameInfo.mPanIds.IsDestinationPresent());
}
if (frame.IsSrcPanIdPresent())
{
SuccessOrQuit(frame.GetSrcPanId(panId));
VerifyOrQuit(panId == panIds.GetSource());
VerifyOrQuit(panIds.IsSourcePresent());
VerifyOrQuit(panId == frameInfo.mPanIds.GetSource());
VerifyOrQuit(frameInfo.mPanIds.IsSourcePresent());
}
if (frame.GetSecurityEnabled())