mirror of
https://github.com/espressif/openthread.git
synced 2026-08-04 18:07:47 +00:00
[mpl] smaller enhancements in Ip6::Mpl (#8475)
- Use MLE `GetMeshLocal16()` to check if seed ID can be elided (remove `mMatchingAddress). - When processing MPL option if seed ID is elided, we ensure that sender's address is RLOC format and use the RLOC16 as seed ID. - When preparing MPL option directly use device's RLOC16 as seed ID (removing `Mpl::Get/SetSeedId()` methods). - Determine number of timer expirations (MPL retransmission) based on device's current role.
This commit is contained in:
+36
-19
@@ -46,13 +46,10 @@ namespace Ip6 {
|
||||
|
||||
Mpl::Mpl(Instance &aInstance)
|
||||
: InstanceLocator(aInstance)
|
||||
, mMatchingAddress(nullptr)
|
||||
, mSeedSetTimer(aInstance)
|
||||
, mSeedId(0)
|
||||
, mSequence(0)
|
||||
#if OPENTHREAD_FTD
|
||||
, mRetransmissionTimer(aInstance)
|
||||
, mTimerExpirations(0)
|
||||
#endif
|
||||
{
|
||||
memset(mSeedSet, 0, sizeof(mSeedSet));
|
||||
@@ -63,18 +60,18 @@ void Mpl::InitOption(OptionMpl &aOption, const Address &aAddress)
|
||||
aOption.Init();
|
||||
aOption.SetSequence(mSequence++);
|
||||
|
||||
// Check if Seed Id can be elided.
|
||||
if (mMatchingAddress && aAddress == *mMatchingAddress)
|
||||
// Seed ID can be elided when `aAddress` is RLOC.
|
||||
if (aAddress == Get<Mle::Mle>().GetMeshLocal16())
|
||||
{
|
||||
aOption.SetSeedIdLength(OptionMpl::kSeedIdLength0);
|
||||
|
||||
// Decrease default option length.
|
||||
aOption.SetLength(aOption.GetLength() - sizeof(mSeedId));
|
||||
aOption.SetLength(aOption.GetLength() - sizeof(uint16_t));
|
||||
}
|
||||
else
|
||||
{
|
||||
aOption.SetSeedIdLength(OptionMpl::kSeedIdLength2);
|
||||
aOption.SetSeedId(mSeedId);
|
||||
aOption.SetSeedId(Get<Mle::Mle>().GetRloc16());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,8 +87,9 @@ Error Mpl::ProcessOption(Message &aMessage, const Address &aAddress, bool aIsOut
|
||||
|
||||
if (option.GetSeedIdLength() == OptionMpl::kSeedIdLength0)
|
||||
{
|
||||
// Retrieve MPL Seed Id from the IPv6 Source Address.
|
||||
option.SetSeedId(HostSwap16(aAddress.mFields.m16[7]));
|
||||
// Retrieve Seed ID from the IPv6 Source Address RLOC.
|
||||
VerifyOrExit(aAddress.GetIid().IsLocator(), error = kErrorDrop);
|
||||
option.SetSeedId(aAddress.GetIid().GetLocator());
|
||||
}
|
||||
|
||||
// Check if the MPL Data Message is new.
|
||||
@@ -292,6 +290,29 @@ void Mpl::HandleSeedSetTimer(void)
|
||||
|
||||
#if OPENTHREAD_FTD
|
||||
|
||||
uint8_t Mpl::GetTimerExpirations(void) const
|
||||
{
|
||||
uint8_t timerExpirations = 0;
|
||||
|
||||
switch (Get<Mle::Mle>().GetRole())
|
||||
{
|
||||
case Mle::kRoleDisabled:
|
||||
case Mle::kRoleDetached:
|
||||
break;
|
||||
|
||||
case Mle::kRoleChild:
|
||||
timerExpirations = kChildTimerExpirations;
|
||||
break;
|
||||
|
||||
case Mle::kRoleRouter:
|
||||
case Mle::kRoleLeader:
|
||||
timerExpirations = kRouterTimerExpirations;
|
||||
break;
|
||||
}
|
||||
|
||||
return timerExpirations;
|
||||
}
|
||||
|
||||
void Mpl::AddBufferedMessage(Message &aMessage, uint16_t aSeedId, uint8_t aSequence, bool aIsOutbound)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
@@ -343,17 +364,16 @@ void Mpl::HandleRetransmissionTimer(void)
|
||||
|
||||
if (now < metadata.mTransmissionTime)
|
||||
{
|
||||
if (nextTime > metadata.mTransmissionTime)
|
||||
{
|
||||
nextTime = metadata.mTransmissionTime;
|
||||
}
|
||||
nextTime = Min(nextTime, metadata.mTransmissionTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t timerExpirations = GetTimerExpirations();
|
||||
|
||||
// Update the number of transmission timer expirations.
|
||||
metadata.mTransmissionCount++;
|
||||
|
||||
if (metadata.mTransmissionCount < GetTimerExpirations())
|
||||
if (metadata.mTransmissionCount < timerExpirations)
|
||||
{
|
||||
Message *messageCopy = message.Clone(message.GetLength() - sizeof(Metadata));
|
||||
|
||||
@@ -370,16 +390,13 @@ void Mpl::HandleRetransmissionTimer(void)
|
||||
metadata.GenerateNextTransmissionTime(now, kDataMessageInterval);
|
||||
metadata.UpdateIn(message);
|
||||
|
||||
if (nextTime > metadata.mTransmissionTime)
|
||||
{
|
||||
nextTime = metadata.mTransmissionTime;
|
||||
}
|
||||
nextTime = Min(nextTime, metadata.mTransmissionTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
mBufferedMessageSet.Dequeue(message);
|
||||
|
||||
if (metadata.mTransmissionCount == GetTimerExpirations())
|
||||
if (metadata.mTransmissionCount == timerExpirations)
|
||||
{
|
||||
if (metadata.mTransmissionCount > 1)
|
||||
{
|
||||
|
||||
+11
-54
@@ -221,49 +221,7 @@ public:
|
||||
*/
|
||||
Error ProcessOption(Message &aMessage, const Address &aAddress, bool aIsOutbound, bool &aReceive);
|
||||
|
||||
/**
|
||||
* This method returns the MPL Seed Id value.
|
||||
*
|
||||
* @returns The MPL Seed Id value.
|
||||
*
|
||||
*/
|
||||
uint16_t GetSeedId(void) const { return mSeedId; }
|
||||
|
||||
/**
|
||||
* This method sets the MPL Seed Id value.
|
||||
*
|
||||
* @param[in] aSeedId The MPL Seed Id value.
|
||||
*
|
||||
*/
|
||||
void SetSeedId(uint16_t aSeedId) { mSeedId = aSeedId; }
|
||||
|
||||
/**
|
||||
* This method sets the IPv6 matching address, that allows to elide MPL Seed Id.
|
||||
*
|
||||
* @param[in] aAddress The reference to the IPv6 matching address.
|
||||
*
|
||||
*/
|
||||
void SetMatchingAddress(const Address &aAddress) { mMatchingAddress = &aAddress; }
|
||||
|
||||
#if OPENTHREAD_FTD
|
||||
/**
|
||||
* This method gets the MPL number of Trickle timer expirations that occur before
|
||||
* terminating the Trickle algorithm's retransmission of a given MPL Data Message.
|
||||
*
|
||||
* @returns The MPL number of Trickle timer expirations.
|
||||
*
|
||||
*/
|
||||
uint8_t GetTimerExpirations(void) const { return mTimerExpirations; }
|
||||
|
||||
/**
|
||||
* This method sets the MPL number of Trickle timer expirations that occur before
|
||||
* terminating the Trickle algorithm's retransmission of a given MPL Data Message.
|
||||
*
|
||||
* @param[in] aTimerExpirations The number of Trickle timer expirations.
|
||||
*
|
||||
*/
|
||||
void SetTimerExpirations(uint8_t aTimerExpirations) { mTimerExpirations = aTimerExpirations; }
|
||||
|
||||
/**
|
||||
* This method returns a reference to the buffered message set.
|
||||
*
|
||||
@@ -271,7 +229,7 @@ public:
|
||||
*
|
||||
*/
|
||||
const MessageQueue &GetBufferedMessageSet(void) const { return mBufferedMessageSet; }
|
||||
#endif // OPENTHREAD_FTD
|
||||
#endif
|
||||
|
||||
private:
|
||||
static constexpr uint16_t kNumSeedEntries = OPENTHREAD_CONFIG_MPL_SEED_SET_ENTRIES;
|
||||
@@ -286,19 +244,19 @@ private:
|
||||
uint8_t mLifetime;
|
||||
};
|
||||
|
||||
void HandleSeedSetTimer(void);
|
||||
|
||||
void HandleSeedSetTimer(void);
|
||||
Error UpdateSeedSet(uint16_t aSeedId, uint8_t aSequence);
|
||||
|
||||
using SeedSetTimer = TimerMilliIn<Mpl, &Mpl::HandleSeedSetTimer>;
|
||||
|
||||
SeedEntry mSeedSet[kNumSeedEntries];
|
||||
const Address *mMatchingAddress;
|
||||
SeedSetTimer mSeedSetTimer;
|
||||
uint16_t mSeedId;
|
||||
uint8_t mSequence;
|
||||
SeedEntry mSeedSet[kNumSeedEntries];
|
||||
SeedSetTimer mSeedSetTimer;
|
||||
uint8_t mSequence;
|
||||
|
||||
#if OPENTHREAD_FTD
|
||||
static constexpr uint8_t kChildTimerExpirations = 0; // MPL retransmissions for Children.
|
||||
static constexpr uint8_t kRouterTimerExpirations = 2; // MPL retransmissions for Routers.
|
||||
|
||||
struct Metadata
|
||||
{
|
||||
Error AppendTo(Message &aMessage) const { return aMessage.Append(*this); }
|
||||
@@ -314,15 +272,14 @@ private:
|
||||
uint8_t mIntervalOffset;
|
||||
};
|
||||
|
||||
void HandleRetransmissionTimer(void);
|
||||
|
||||
void AddBufferedMessage(Message &aMessage, uint16_t aSeedId, uint8_t aSequence, bool aIsOutbound);
|
||||
uint8_t GetTimerExpirations(void) const;
|
||||
void HandleRetransmissionTimer(void);
|
||||
void AddBufferedMessage(Message &aMessage, uint16_t aSeedId, uint8_t aSequence, bool aIsOutbound);
|
||||
|
||||
using RetxTimer = TimerMilliIn<Mpl, &Mpl::HandleRetransmissionTimer>;
|
||||
|
||||
MessageQueue mBufferedMessageSet;
|
||||
RetxTimer mRetransmissionTimer;
|
||||
uint8_t mTimerExpirations;
|
||||
#endif // OPENTHREAD_FTD
|
||||
};
|
||||
|
||||
|
||||
@@ -130,9 +130,6 @@ Mle::Mle(Instance &aInstance)
|
||||
mMeshLocal16.GetAddress().GetIid().SetToLocator(0);
|
||||
mMeshLocal16.mRloc = true;
|
||||
|
||||
// Store RLOC address reference in MPL module.
|
||||
Get<Ip6::Mpl>().SetMatchingAddress(mMeshLocal16.GetAddress());
|
||||
|
||||
mLinkLocalAllThreadNodes.Clear();
|
||||
mLinkLocalAllThreadNodes.GetAddress().mFields.m16[0] = HostSwap16(0xff32);
|
||||
mLinkLocalAllThreadNodes.GetAddress().mFields.m16[7] = HostSwap16(0x0001);
|
||||
@@ -701,9 +698,6 @@ void Mle::SetStateDetached(void)
|
||||
Get<MleRouter>().HandleDetachStart();
|
||||
#endif
|
||||
Get<Ip6::Ip6>().SetForwardingEnabled(false);
|
||||
#if OPENTHREAD_FTD
|
||||
Get<Ip6::Mpl>().SetTimerExpirations(0);
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
||||
Get<Mac::Mac>().UpdateCsl();
|
||||
#endif
|
||||
@@ -734,9 +728,6 @@ void Mle::SetStateChild(uint16_t aRloc16)
|
||||
#endif
|
||||
|
||||
Get<Ip6::Ip6>().SetForwardingEnabled(false);
|
||||
#if OPENTHREAD_FTD
|
||||
Get<Ip6::Mpl>().SetTimerExpirations(kMplChildDataMessageTimerExpirations);
|
||||
#endif
|
||||
|
||||
// send announce after attached if needed
|
||||
InformPreviousChannel();
|
||||
@@ -992,7 +983,6 @@ void Mle::SetRloc16(uint16_t aRloc16)
|
||||
}
|
||||
|
||||
Get<Mac::Mac>().SetShortAddress(aRloc16);
|
||||
Get<Ip6::Mpl>().SetSeedId(aRloc16);
|
||||
|
||||
if (aRloc16 != Mac::kShortAddrInvalid)
|
||||
{
|
||||
|
||||
@@ -381,7 +381,6 @@ void MleRouter::SetStateRouter(uint16_t aRloc16)
|
||||
Get<ThreadNetif>().SubscribeAllRoutersMulticast();
|
||||
mPreviousPartitionIdRouter = mLeaderData.GetPartitionId();
|
||||
Get<Ip6::Ip6>().SetForwardingEnabled(true);
|
||||
Get<Ip6::Mpl>().SetTimerExpirations(kMplRouterDataMessageTimerExpirations);
|
||||
Get<Mac::Mac>().SetBeaconEnabled(true);
|
||||
|
||||
// remove children that do not have matching RLOC16
|
||||
@@ -422,7 +421,6 @@ void MleRouter::SetStateLeader(uint16_t aRloc16, LeaderStartMode aStartMode)
|
||||
Get<MeshCoP::ActiveDatasetManager>().StartLeader();
|
||||
Get<MeshCoP::PendingDatasetManager>().StartLeader();
|
||||
Get<Ip6::Ip6>().SetForwardingEnabled(true);
|
||||
Get<Ip6::Mpl>().SetTimerExpirations(kMplRouterDataMessageTimerExpirations);
|
||||
Get<Mac::Mac>().SetBeaconEnabled(true);
|
||||
Get<AddressResolver>().Clear();
|
||||
|
||||
|
||||
@@ -188,9 +188,6 @@ constexpr uint8_t kLinkQuality2LinkCost = 2; ///< Link Cost for Link
|
||||
constexpr uint8_t kLinkQuality1LinkCost = 4; ///< Link Cost for Link Quality 1
|
||||
constexpr uint8_t kLinkQuality0LinkCost = kMaxRouteCost; ///< Link Cost for Link Quality 0
|
||||
|
||||
constexpr uint8_t kMplChildDataMessageTimerExpirations = 0; ///< Number of MPL retransmissions for Children.
|
||||
constexpr uint8_t kMplRouterDataMessageTimerExpirations = 2; ///< Number of MPL retransmissions for Routers.
|
||||
|
||||
/**
|
||||
* This type represents a Thread device role.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user