mirror of
https://github.com/espressif/openthread.git
synced 2026-08-09 20:27:47 +00:00
fix RFD child reattach issue when the parent is in new partition without changing routerid (#161)
choose a random initial mRouterIdSequence when forming a new partition
This commit is contained in:
+51
-7
@@ -67,6 +67,7 @@ Mle::Mle(ThreadNetif &aThreadNetif) :
|
||||
mParentRequestState = kParentIdle;
|
||||
mParentRequestMode = kMleAttachAnyPartition;
|
||||
mParentConnectivity = 0;
|
||||
mRetrieveNewNetworkData = false;
|
||||
mTimeout = kMaxNeighborAge;
|
||||
|
||||
memset(&mLeaderData, 0, sizeof(mLeaderData));
|
||||
@@ -1415,10 +1416,21 @@ ThreadError Mle::HandleAdvertisement(const Message &aMessage, const Ip6::Message
|
||||
Mac::ExtAddress macAddr;
|
||||
bool isNeighbor;
|
||||
Neighbor *neighbor;
|
||||
SourceAddressTlv sourceAddress;
|
||||
LeaderDataTlv leaderData;
|
||||
uint8_t tlvs[] = {Tlv::kLeaderData, Tlv::kNetworkData};
|
||||
|
||||
if (mDeviceState != kDeviceStateDetached)
|
||||
// Source Address
|
||||
SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kSourceAddress, sizeof(sourceAddress), sourceAddress));
|
||||
VerifyOrExit(sourceAddress.IsValid(), error = kThreadError_Parse);
|
||||
|
||||
// Leader Data
|
||||
SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kLeaderData, sizeof(leaderData), leaderData));
|
||||
VerifyOrExit(leaderData.IsValid(), error = kThreadError_Parse);
|
||||
|
||||
otLogInfoMle("Received advertisement from %04x\n", sourceAddress.GetRloc16());
|
||||
|
||||
if ((mDeviceState != kDeviceStateDetached) && (mDeviceMode & ModeTlv::kModeFFD))
|
||||
{
|
||||
SuccessOrExit(error = mMleRouter.HandleAdvertisement(aMessage, aMessageInfo));
|
||||
}
|
||||
@@ -1439,6 +1451,21 @@ ThreadError Mle::HandleAdvertisement(const Message &aMessage, const Ip6::Message
|
||||
break;
|
||||
}
|
||||
|
||||
if (mParent.mValid.mRloc16 != sourceAddress.GetRloc16())
|
||||
{
|
||||
SetStateDetached();
|
||||
ExitNow(error = kThreadError_NoRoute);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (leaderData.GetPartitionId() != mLeaderData.GetPartitionId() ||
|
||||
leaderData.GetLeaderRouterId() != GetLeaderId())
|
||||
{
|
||||
SetLeaderData(leaderData.GetPartitionId(), leaderData.GetWeighting(), leaderData.GetLeaderRouterId());
|
||||
mRetrieveNewNetworkData = true;
|
||||
}
|
||||
}
|
||||
|
||||
isNeighbor = true;
|
||||
mParent.mLastHeard = mParentRequestTimer.GetNow();
|
||||
break;
|
||||
@@ -1456,10 +1483,8 @@ ThreadError Mle::HandleAdvertisement(const Message &aMessage, const Ip6::Message
|
||||
|
||||
if (isNeighbor)
|
||||
{
|
||||
SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kLeaderData, sizeof(leaderData), leaderData));
|
||||
VerifyOrExit(leaderData.IsValid(), error = kThreadError_Parse);
|
||||
|
||||
if (static_cast<int8_t>(leaderData.GetDataVersion() - mNetworkData.GetVersion()) > 0)
|
||||
if (mRetrieveNewNetworkData ||
|
||||
(static_cast<int8_t>(leaderData.GetDataVersion() - mNetworkData.GetVersion()) > 0))
|
||||
{
|
||||
SendDataRequest(aMessageInfo.GetPeerAddr(), tlvs, sizeof(tlvs));
|
||||
}
|
||||
@@ -1499,8 +1524,27 @@ ThreadError Mle::HandleDataResponse(const Message &aMessage, const Ip6::MessageI
|
||||
SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kLeaderData, sizeof(leaderData), leaderData));
|
||||
VerifyOrExit(leaderData.IsValid(), error = kThreadError_Parse);
|
||||
|
||||
diff = leaderData.GetDataVersion() - mNetworkData.GetVersion();
|
||||
VerifyOrExit(diff > 0, ;);
|
||||
if ((leaderData.GetPartitionId() != mLeaderData.GetPartitionId()) ||
|
||||
(leaderData.GetLeaderRouterId() != GetLeaderId()))
|
||||
{
|
||||
if ((mDeviceMode & ModeTlv::kModeRxOnWhenIdle) == 0)
|
||||
{
|
||||
SetLeaderData(leaderData.GetPartitionId(), leaderData.GetWeighting(), leaderData.GetLeaderRouterId());
|
||||
}
|
||||
else
|
||||
{
|
||||
ExitNow(error = kThreadError_Drop);
|
||||
}
|
||||
}
|
||||
else if (mRetrieveNewNetworkData)
|
||||
{
|
||||
mRetrieveNewNetworkData = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
diff = leaderData.GetDataVersion() - mNetworkData.GetVersion();
|
||||
VerifyOrExit(diff > 0, ;);
|
||||
}
|
||||
|
||||
mNetworkData.SetNetworkData(leaderData.GetDataVersion(), leaderData.GetStableDataVersion(),
|
||||
(mDeviceMode & ModeTlv::kModeFullNetworkData) == 0,
|
||||
|
||||
@@ -907,6 +907,7 @@ protected:
|
||||
NetworkData::Leader &mNetworkData; ///< The Network Data object.
|
||||
|
||||
LeaderDataTlv mLeaderData; ///< Last received Leader Data TLV.
|
||||
bool mRetrieveNewNetworkData; ///< Indicating new Network Data is needed if set.
|
||||
|
||||
DeviceState mDeviceState; ///< Current Thread interface state.
|
||||
Router mParent; ///< Parent information.
|
||||
|
||||
@@ -228,6 +228,7 @@ ThreadError MleRouter::BecomeLeader(void)
|
||||
memcpy(&mRouters[mRouterId].mMacAddr, mMac.GetExtAddress(), sizeof(mRouters[mRouterId].mMacAddr));
|
||||
|
||||
SetLeaderData(otPlatRandomGet(), mLeaderWeight, mRouterId);
|
||||
mRouterIdSequence = otPlatRandomGet();
|
||||
|
||||
mNetworkData.Reset();
|
||||
|
||||
@@ -1083,7 +1084,6 @@ ThreadError MleRouter::HandleAdvertisement(const Message &aMessage, const Ip6::M
|
||||
|
||||
// Source Address
|
||||
SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kSourceAddress, sizeof(sourceAddress), sourceAddress));
|
||||
VerifyOrExit(sourceAddress.IsValid(), error = kThreadError_Parse);
|
||||
|
||||
// Remove stale neighbors
|
||||
if ((neighbor = GetNeighbor(macAddr)) != NULL &&
|
||||
@@ -1094,9 +1094,6 @@ ThreadError MleRouter::HandleAdvertisement(const Message &aMessage, const Ip6::M
|
||||
|
||||
// Leader Data
|
||||
SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kLeaderData, sizeof(leaderData), leaderData));
|
||||
VerifyOrExit(leaderData.IsValid(), error = kThreadError_Parse);
|
||||
|
||||
otLogInfoMle("Received advertisement from %04x\n", sourceAddress.GetRloc16());
|
||||
|
||||
peerParitionId = leaderData.GetPartitionId();
|
||||
|
||||
@@ -1128,10 +1125,7 @@ ThreadError MleRouter::HandleAdvertisement(const Message &aMessage, const Ip6::M
|
||||
SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kRoute, sizeof(route), route));
|
||||
VerifyOrExit(route.IsValid(), error = kThreadError_Parse);
|
||||
|
||||
if (mDeviceMode & ModeTlv::kModeFFD)
|
||||
{
|
||||
SuccessOrExit(error = ProcessRouteTlv(route));
|
||||
}
|
||||
SuccessOrExit(error = ProcessRouteTlv(route));
|
||||
|
||||
VerifyOrExit((routerId = GetRouterId(sourceAddress.GetRloc16())) < kMaxRouterId, error = kThreadError_Parse);
|
||||
|
||||
@@ -1154,7 +1148,7 @@ ThreadError MleRouter::HandleAdvertisement(const Message &aMessage, const Ip6::M
|
||||
}
|
||||
}
|
||||
|
||||
if ((mDeviceMode & ModeTlv::kModeFFD) && (routerCount < mRouterUpgradeThreshold))
|
||||
if (routerCount < mRouterUpgradeThreshold)
|
||||
{
|
||||
BecomeRouter();
|
||||
ExitNow();
|
||||
|
||||
Reference in New Issue
Block a user