Skip to content

Commit

Permalink
[mac-frame] add TxFrame::Info and simplify mac header preparation (o…
Browse files Browse the repository at this point in the history
…penthread#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).
  • Loading branch information
abtink authored Oct 1, 2024
1 parent 3a28b7b commit 09698fa
Show file tree
Hide file tree
Showing 10 changed files with 245 additions and 185 deletions.
16 changes: 14 additions & 2 deletions src/core/common/frame_builder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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); }
Expand Down Expand Up @@ -118,6 +118,18 @@ Error FrameBuilder::AppendBytesFromMessage(const Message &aMessage, uint16_t aOf
}
#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);
Expand Down
36 changes: 34 additions & 2 deletions src/core/common/frame_builder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,9 @@ class FrameBuilder
* `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.
Expand Down Expand Up @@ -211,6 +211,38 @@ class FrameBuilder
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.
*
Expand Down
24 changes: 13 additions & 11 deletions src/core/mac/data_poll_sender.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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())
Expand Down
34 changes: 19 additions & 15 deletions src/core/mac/mac.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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));

Expand All @@ -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;
Expand All @@ -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();

frameInfo.mType = Frame::kTypeBeacon;
frameInfo.mVersion = Frame::kVersion2003;

frame->InitMacHeader(Frame::kTypeBeacon, Frame::kVersion2003, addrs, panIds, Frame::kSecurityNone);
frameInfo.PrepareHeadersIn(*frame);

beacon = reinterpret_cast<Beacon *>(frame->GetPayload());
beacon->Init();
Expand Down
Loading

0 comments on commit 09698fa

Please sign in to comment.