mirror of
https://github.com/espressif/openthread.git
synced 2026-08-12 05:37:46 +00:00
[mle] update processing of received MLE Announce messages (#2707)
This commit changes how the received MLE Announce messages are processed. The new implementation adds a delay before taking action when it receives an MLE Announce message that has a more recent Active timestamp (compared to device's current Active Dataset timestamp). A timeout interval of `kAnnounceProcessTimeout` (250ms) is used before the device switches to the new channel or pan-id from the received MLE Announce message. During the timeout interval, device can receive and parse other MLE Announce messages and it will ignore any with the same timestamp.
This commit is contained in:
committed by
Jonathan Hui
parent
c276d0776c
commit
38f206c670
+57
-20
@@ -101,8 +101,9 @@ Mle::Mle(Instance &aInstance)
|
||||
, mParentSearchTimer(aInstance, &Mle::HandleParentSearchTimer, this)
|
||||
#endif
|
||||
, mAnnounceChannel(OT_RADIO_CHANNEL_MIN)
|
||||
, mPreviousChannel(0)
|
||||
, mPreviousPanId(Mac::kPanIdBroadcast)
|
||||
, mAlternateChannel(0)
|
||||
, mAlternatePanId(Mac::kPanIdBroadcast)
|
||||
, mAlternateTimestamp(0)
|
||||
, mNotifierCallback(&Mle::HandleStateChanged, this)
|
||||
{
|
||||
uint8_t meshLocalPrefix[8];
|
||||
@@ -658,14 +659,14 @@ otError Mle::SetStateChild(uint16_t aRloc16)
|
||||
|
||||
void Mle::InformPreviousChannel(void)
|
||||
{
|
||||
VerifyOrExit(mPreviousPanId != Mac::kPanIdBroadcast);
|
||||
VerifyOrExit(mAlternatePanId != Mac::kPanIdBroadcast);
|
||||
VerifyOrExit(mRole == OT_DEVICE_ROLE_CHILD || mRole == OT_DEVICE_ROLE_ROUTER);
|
||||
|
||||
if (!IsFullThreadDevice() || mRole == OT_DEVICE_ROLE_ROUTER ||
|
||||
GetNetif().GetMle().GetRouterSelectionJitterTimeout() == 0)
|
||||
{
|
||||
mPreviousPanId = Mac::kPanIdBroadcast;
|
||||
GetNetif().GetAnnounceBeginServer().SendAnnounce(1 << mPreviousChannel);
|
||||
mAlternatePanId = Mac::kPanIdBroadcast;
|
||||
GetNetif().GetAnnounceBeginServer().SendAnnounce(1 << mAlternateChannel);
|
||||
}
|
||||
|
||||
exit:
|
||||
@@ -1478,6 +1479,10 @@ void Mle::HandleAttachTimer(void)
|
||||
SendChildUpdateRequest();
|
||||
break;
|
||||
|
||||
case kAttachStateProcessAnnounce:
|
||||
ProcessAnnounce();
|
||||
break;
|
||||
|
||||
case kAttachStateStart:
|
||||
SetAttachState(kAttachStateParentRequestRouter);
|
||||
mParentCandidate.SetState(Neighbor::kStateInvalid);
|
||||
@@ -1615,11 +1620,11 @@ uint32_t Mle::Reattach(void)
|
||||
case kAttachAny:
|
||||
if (mRole != OT_DEVICE_ROLE_CHILD)
|
||||
{
|
||||
if (mPreviousPanId != Mac::kPanIdBroadcast)
|
||||
if (mAlternatePanId != Mac::kPanIdBroadcast)
|
||||
{
|
||||
netif.GetMac().SetPanChannel(mPreviousChannel);
|
||||
netif.GetMac().SetPanId(mPreviousPanId);
|
||||
mPreviousPanId = Mac::kPanIdBroadcast;
|
||||
netif.GetMac().SetPanChannel(mAlternateChannel);
|
||||
netif.GetMac().SetPanId(mAlternatePanId);
|
||||
mAlternatePanId = Mac::kPanIdBroadcast;
|
||||
BecomeDetached();
|
||||
}
|
||||
else if (!IsFullThreadDevice())
|
||||
@@ -3268,7 +3273,6 @@ exit:
|
||||
|
||||
otError Mle::HandleAnnounce(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
|
||||
{
|
||||
ThreadNetif & netif = GetNetif();
|
||||
otError error = OT_ERROR_NONE;
|
||||
ChannelTlv channelTlv;
|
||||
ActiveTimestampTlv timestamp;
|
||||
@@ -3290,25 +3294,31 @@ otError Mle::HandleAnnounce(const Message &aMessage, const Ip6::MessageInfo &aMe
|
||||
VerifyOrExit(panIdTlv.IsValid(), error = OT_ERROR_PARSE);
|
||||
panId = panIdTlv.GetPanId();
|
||||
|
||||
localTimestamp = netif.GetActiveDataset().GetTimestamp();
|
||||
localTimestamp = GetNetif().GetActiveDataset().GetTimestamp();
|
||||
|
||||
if (localTimestamp == NULL || localTimestamp->Compare(timestamp) > 0)
|
||||
{
|
||||
uint8_t curChannel = netif.GetMac().GetPanChannel();
|
||||
uint16_t curPanId = netif.GetMac().GetPanId();
|
||||
Mac::Mac &mac = GetNetif().GetMac();
|
||||
|
||||
// No action is required if device is detached, and current
|
||||
// channel and pan-id match the values from the received MLE
|
||||
// Announce message.
|
||||
|
||||
VerifyOrExit((mRole != OT_DEVICE_ROLE_DETACHED) || (curChannel != channel) || (curPanId != panId));
|
||||
VerifyOrExit((mRole != OT_DEVICE_ROLE_DETACHED) || (mac.GetPanChannel() != channel) ||
|
||||
(mac.GetPanId() != panId));
|
||||
|
||||
Stop(false);
|
||||
mPreviousChannel = curChannel;
|
||||
mPreviousPanId = curPanId;
|
||||
netif.GetMac().SetPanChannel(channel);
|
||||
netif.GetMac().SetPanId(panId);
|
||||
Start(false, true);
|
||||
if (mAttachState == kAttachStateProcessAnnounce)
|
||||
{
|
||||
VerifyOrExit(mAlternateTimestamp < timestamp.GetSeconds());
|
||||
}
|
||||
|
||||
mAlternateTimestamp = timestamp.GetSeconds();
|
||||
mAlternateChannel = channel;
|
||||
mAlternatePanId = panId;
|
||||
SetAttachState(kAttachStateProcessAnnounce);
|
||||
mAttachTimer.Start(kAnnounceProcessTimeout);
|
||||
|
||||
otLogInfoMle(GetInstance(), "Delay processing Announce - channel %d, panid 0x%02x", channel, panId);
|
||||
}
|
||||
else if (localTimestamp->Compare(timestamp) < 0)
|
||||
{
|
||||
@@ -3331,6 +3341,29 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
void Mle::ProcessAnnounce(void)
|
||||
{
|
||||
Mac::Mac &mac = GetNetif().GetMac();
|
||||
uint8_t newChannel = mAlternateChannel;
|
||||
uint16_t newPanId = mAlternatePanId;
|
||||
|
||||
assert(mAttachState == kAttachStateProcessAnnounce);
|
||||
|
||||
otLogInfoMle(GetInstance(), "Processing Announce - channel %d, panid 0x%02x", newChannel, newPanId);
|
||||
|
||||
Stop(/* aClearNetworkDatasets */ false);
|
||||
|
||||
// Save the current/previous channel and pan-id
|
||||
mAlternateChannel = mac.GetPanChannel();
|
||||
mAlternatePanId = mac.GetPanId();
|
||||
mAlternateTimestamp = 0;
|
||||
|
||||
mac.SetPanChannel(newChannel);
|
||||
mac.SetPanId(newPanId);
|
||||
|
||||
Start(/* aEnableReattach */ false, /* aAnnounceAttach */ true);
|
||||
}
|
||||
|
||||
otError Mle::HandleDiscoveryResponse(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
@@ -3820,6 +3853,10 @@ const char *Mle::AttachStateToString(AttachState aState)
|
||||
str = "Sync";
|
||||
break;
|
||||
|
||||
case kAttachStateProcessAnnounce:
|
||||
str = "ProcessAnnounce";
|
||||
break;
|
||||
|
||||
case kAttachStateStart:
|
||||
str = "Start";
|
||||
break;
|
||||
|
||||
@@ -998,6 +998,7 @@ protected:
|
||||
{
|
||||
kAttachStateIdle, ///< Not currently searching for a parent.
|
||||
kAttachStateSynchronize, ///< Looking to synchronize with a parent (after reset).
|
||||
kAttachStateProcessAnnounce, ///< Waiting to process a received Announce (to switch channel/pan-id).
|
||||
kAttachStateStart, ///< Starting to look for a parent.
|
||||
kAttachStateParentRequestRouter, ///< Searching for a Router to attach to.
|
||||
kAttachStateParentRequestReed, ///< Searching for Routers or REEDs to attach to.
|
||||
@@ -1565,6 +1566,7 @@ private:
|
||||
otError HandleAnnounce(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
|
||||
otError HandleDiscoveryResponse(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
|
||||
otError HandleLeaderData(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
|
||||
void ProcessAnnounce(void);
|
||||
|
||||
otError SendParentRequest(ParentRequestType aType);
|
||||
otError SendChildIdRequest(void);
|
||||
@@ -1644,8 +1646,9 @@ private:
|
||||
#endif
|
||||
|
||||
uint8_t mAnnounceChannel;
|
||||
uint8_t mPreviousChannel;
|
||||
uint16_t mPreviousPanId;
|
||||
uint8_t mAlternateChannel;
|
||||
uint16_t mAlternatePanId;
|
||||
uint64_t mAlternateTimestamp;
|
||||
|
||||
Ip6::NetifUnicastAddress mLeaderAloc;
|
||||
|
||||
|
||||
@@ -62,6 +62,7 @@ enum
|
||||
kParentRequestRouterTimeout = 750, ///< Router Parent Request timeout
|
||||
kParentRequestReedTimeout = 1250, ///< Router and REEDs Parent Request timeout
|
||||
kParentRequestJitter = 50, ///< Maximum jitter time added to Parent Request timeout
|
||||
kAnnounceProcessTimeout = 250, ///< Timeout after receiving Announcement before channel/pan-id change
|
||||
kAnnounceTimeout = 1400, ///< Total timeout used for sending Announcement messages
|
||||
kMinAnnounceDelay = 80, ///< Minimum delay between Announcement messages
|
||||
kParentResponseMaxDelayRouters = 500, ///< Maximum delay for response for Parent Request sent to routers only
|
||||
|
||||
Reference in New Issue
Block a user