mirror of
https://github.com/espressif/openthread.git
synced 2026-08-18 08:29:52 +00:00
[mle] send a unicast MLE Announce in response to a received Announce (#2669)
This commit changes how MLE Announce messages are sent in response to a received MLE Announce. In addition to a multicast MLE Announce message, a unicast MLE Announce is also sent. This behavior can be controlled using `OPENTHREAD_CONFIG_SEND_UNICAST_ANNOUNCE_RESPONSE` config option. By default this is enabled. This commit also changes actions taken after receiving an MLE Announce in `Mle::HandleAnnounce()` to handle the situation where a device may receive multiple MLE Announce messages with same info. No action is taken if the device is detached, and current channel and panid match the values from the received MLE Announce message.
This commit is contained in:
committed by
Jonathan Hui
parent
51d487ed57
commit
dc16c5e694
@@ -1327,6 +1327,19 @@
|
||||
#define OPENTHREAD_CONFIG_PARENT_SEARCH_RSS_THRESHOLD -65
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_SEND_UNICAST_ANNOUNCE_RESPONSE
|
||||
*
|
||||
* Define as 1 to enable sending of a unicast MLE Announce message in response to a received Announce message from
|
||||
* a device.
|
||||
*
|
||||
* @note The unicast MLE announce message is sent in addition to (and after) the multicast MLE Announce.
|
||||
*
|
||||
*/
|
||||
#ifndef OPENTHREAD_CONFIG_SEND_UNICAST_ANNOUNCE_RESPONSE
|
||||
#define OPENTHREAD_CONFIG_SEND_UNICAST_ANNOUNCE_RESPONSE 1
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_NCP_ENABLE_PEEK_POKE
|
||||
*
|
||||
|
||||
+40
-17
@@ -1979,13 +1979,23 @@ exit:
|
||||
}
|
||||
|
||||
otError Mle::SendAnnounce(uint8_t aChannel, bool aOrphanAnnounce)
|
||||
{
|
||||
Ip6::Address destination;
|
||||
|
||||
memset(&destination, 0, sizeof(destination));
|
||||
destination.mFields.m16[0] = HostSwap16(0xff02);
|
||||
destination.mFields.m16[7] = HostSwap16(0x0001);
|
||||
|
||||
return SendAnnounce(aChannel, aOrphanAnnounce, destination);
|
||||
}
|
||||
|
||||
otError Mle::SendAnnounce(uint8_t aChannel, bool aOrphanAnnounce, const Ip6::Address &aDestination)
|
||||
{
|
||||
ThreadNetif & netif = GetNetif();
|
||||
otError error = OT_ERROR_NONE;
|
||||
ChannelTlv channel;
|
||||
PanIdTlv panid;
|
||||
ActiveTimestampTlv activeTimestamp;
|
||||
Ip6::Address destination;
|
||||
Message * message;
|
||||
|
||||
VerifyOrExit((message = NewMleMessage()) != NULL, error = OT_ERROR_NO_BUFS);
|
||||
@@ -2016,11 +2026,7 @@ otError Mle::SendAnnounce(uint8_t aChannel, bool aOrphanAnnounce)
|
||||
panid.Init();
|
||||
panid.SetPanId(netif.GetMac().GetPanId());
|
||||
SuccessOrExit(error = message->Append(&panid, sizeof(panid)));
|
||||
|
||||
memset(&destination, 0, sizeof(destination));
|
||||
destination.mFields.m16[0] = HostSwap16(0xff02);
|
||||
destination.mFields.m16[7] = HostSwap16(0x0001);
|
||||
SuccessOrExit(error = SendMessage(*message, destination));
|
||||
SuccessOrExit(error = SendMessage(*message, aDestination));
|
||||
|
||||
otLogInfoMle(GetInstance(), "Send Announce on channel %d", aChannel);
|
||||
|
||||
@@ -3188,36 +3194,53 @@ otError Mle::HandleAnnounce(const Message &aMessage, const Ip6::MessageInfo &aMe
|
||||
{
|
||||
ThreadNetif & netif = GetNetif();
|
||||
otError error = OT_ERROR_NONE;
|
||||
ChannelTlv channel;
|
||||
ChannelTlv channelTlv;
|
||||
ActiveTimestampTlv timestamp;
|
||||
const MeshCoP::Timestamp *localTimestamp;
|
||||
PanIdTlv panid;
|
||||
PanIdTlv panIdTlv;
|
||||
uint8_t channel;
|
||||
uint16_t panId;
|
||||
|
||||
LogMleMessage("Receive Announce", aMessageInfo.GetPeerAddr());
|
||||
|
||||
SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kChannel, sizeof(channel), channel));
|
||||
VerifyOrExit(channel.IsValid(), error = OT_ERROR_PARSE);
|
||||
SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kChannel, sizeof(channelTlv), channelTlv));
|
||||
VerifyOrExit(channelTlv.IsValid(), error = OT_ERROR_PARSE);
|
||||
channel = static_cast<uint8_t>(channelTlv.GetChannel());
|
||||
|
||||
SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kActiveTimestamp, sizeof(timestamp), timestamp));
|
||||
VerifyOrExit(timestamp.IsValid(), error = OT_ERROR_PARSE);
|
||||
|
||||
SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kPanId, sizeof(panid), panid));
|
||||
VerifyOrExit(panid.IsValid(), error = OT_ERROR_PARSE);
|
||||
SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kPanId, sizeof(panIdTlv), panIdTlv));
|
||||
VerifyOrExit(panIdTlv.IsValid(), error = OT_ERROR_PARSE);
|
||||
panId = panIdTlv.GetPanId();
|
||||
|
||||
localTimestamp = netif.GetActiveDataset().GetTimestamp();
|
||||
|
||||
if (localTimestamp == NULL || localTimestamp->Compare(timestamp) > 0)
|
||||
{
|
||||
uint8_t curChannel = netif.GetMac().GetChannel();
|
||||
uint16_t curPanId = netif.GetMac().GetPanId();
|
||||
|
||||
// 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));
|
||||
|
||||
Stop(false);
|
||||
mPreviousChannel = netif.GetMac().GetChannel();
|
||||
mPreviousPanId = netif.GetMac().GetPanId();
|
||||
netif.GetMac().SetChannel(static_cast<uint8_t>(channel.GetChannel()));
|
||||
netif.GetMac().SetPanId(panid.GetPanId());
|
||||
mPreviousChannel = curChannel;
|
||||
mPreviousPanId = curPanId;
|
||||
netif.GetMac().SetChannel(channel);
|
||||
netif.GetMac().SetPanId(panId);
|
||||
Start(false, true);
|
||||
}
|
||||
else if (localTimestamp->Compare(timestamp) < 0)
|
||||
{
|
||||
SendAnnounce(static_cast<uint8_t>(channel.GetChannel()), false);
|
||||
SendAnnounce(channel, false);
|
||||
|
||||
#if OPENTHREAD_CONFIG_SEND_UNICAST_ANNOUNCE_RESPONSE
|
||||
SendAnnounce(channel, false, aMessageInfo.GetPeerAddr());
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -1483,6 +1483,7 @@ private:
|
||||
otError SendParentRequest(void);
|
||||
otError SendChildIdRequest(void);
|
||||
void SendOrphanAnnounce(void);
|
||||
otError SendAnnounce(uint8_t aChannel, bool aOrphanAnnounce, const Ip6::Address &aDestination);
|
||||
|
||||
bool IsBetterParent(uint16_t aRloc16, uint8_t aLinkQuality, uint8_t aLinkMargin, ConnectivityTlv &aConnectivityTlv);
|
||||
void ResetParentCandidate(void);
|
||||
|
||||
Reference in New Issue
Block a user