Restrict the condition to SendAddressRelease (#1013)

* Restrict the condition to SendAddressRelease

* some enhancement for AttachSamePartition feature

* code cleanup and implement PARENT_PARTITION_CHANGE
This commit is contained in:
rongli
2016-11-29 12:14:54 -08:00
committed by Jonathan Hui
parent 24b98dbb85
commit 2fec3abdb0
7 changed files with 150 additions and 53 deletions
+12 -12
View File
@@ -287,6 +287,7 @@ ThreadError Mle::Restore()
else if (networkInfo.mDeviceState == kDeviceStateRouter || networkInfo.mDeviceState == kDeviceStateLeader)
{
mMleRouter.SetRouterId(GetRouterId(GetRloc16()));
mMleRouter.SetPreviousPartitionId(networkInfo.mPreviousPartitionId);
mMleRouter.RestoreChildren();
}
@@ -315,6 +316,7 @@ ThreadError Mle::Store()
networkInfo.mKeySequence = mKeyManager.GetCurrentKeySequence();
networkInfo.mMleFrameCounter = mKeyManager.GetMleFrameCounter() + OPENTHREAD_CONFIG_STORE_FRAME_COUNTER_AHEAD;
networkInfo.mMacFrameCounter = mKeyManager.GetMacFrameCounter() + OPENTHREAD_CONFIG_STORE_FRAME_COUNTER_AHEAD;
networkInfo.mPreviousPartitionId = mLeaderData.GetPartitionId();
memcpy(networkInfo.mExtAddress.m8, mMac.GetExtAddress(), sizeof(networkInfo.mExtAddress));
if (mDeviceState == kDeviceStateChild)
@@ -2523,15 +2525,6 @@ ThreadError Mle::HandleChildIdResponse(const Message &aMessage, const Ip6::Messa
mMesh.SetRxOnWhenIdle(true);
}
mParent.mValid.mRloc16 = sourceAddress.GetRloc16();
SuccessOrExit(error = SetStateChild(shortAddress.GetRloc16()));
mNetworkData.SetNetworkData(leaderData.GetDataVersion(), leaderData.GetStableDataVersion(),
(mDeviceMode & ModeTlv::kModeFullNetworkData) == 0,
networkData.GetNetworkData(), networkData.GetLength());
mNetif.GetActiveDataset().ApplyConfiguration();
// Route
if ((Tlv::GetTlv(aMessage, Tlv::kRoute, sizeof(route), route) == kThreadError_None) &&
(mDeviceMode & ModeTlv::kModeFFD))
@@ -2546,14 +2539,21 @@ ThreadError Mle::HandleChildIdResponse(const Message &aMessage, const Ip6::Messa
}
}
if (mRouterSelectionJitterTimeout == 0 &&
(mDeviceMode & ModeTlv::kModeFFD) &&
(numRouters < mMleRouter.GetRouterUpgradeThreshold()))
if (mRouterSelectionJitterTimeout == 0 && numRouters < mMleRouter.GetRouterUpgradeThreshold())
{
mRouterSelectionJitterTimeout = (otPlatRandomGet() % mRouterSelectionJitter) + 1;
}
}
mParent.mValid.mRloc16 = sourceAddress.GetRloc16();
SuccessOrExit(error = SetStateChild(shortAddress.GetRloc16()));
mNetworkData.SetNetworkData(leaderData.GetDataVersion(), leaderData.GetStableDataVersion(),
(mDeviceMode & ModeTlv::kModeFullNetworkData) == 0,
networkData.GetNetworkData(), networkData.GetLength());
mNetif.GetActiveDataset().ApplyConfiguration();
exit:
if (error != kThreadError_None)
+1
View File
@@ -1263,6 +1263,7 @@ private:
uint32_t mKeySequence; ///< Key Sequence
uint32_t mMleFrameCounter; ///< MLE Frame Counter
uint32_t mMacFrameCounter; ///< MAC Frame Counter
uint32_t mPreviousPartitionId; ///< PartitionId
Mac::ExtAddress mExtAddress; ///< Extended Address
} NetworkInfo;
+121 -39
View File
@@ -75,8 +75,9 @@ MleRouter::MleRouter(ThreadNetif &aThreadNetif):
mLeaderWeight = kLeaderWeight;
mFixedLeaderPartitionId = 0;
mMaxChildrenAllowed = kMaxChildren;
mRouterId = kInvalidRouterId;
mPreviousRouterId = kInvalidRouterId;
SetRouterId(kInvalidRouterId);
mPreviousPartitionId = 0;
mRouterIdSequenceLastUpdated = 0;
mRouterRoleEnabled = true;
}
@@ -221,6 +222,7 @@ ThreadError MleRouter::BecomeRouter(ThreadStatusTlv::Status aStatus)
mAdvertiseTimer.Stop();
mAddressResolver.Clear();
mRouterSelectionJitterTimeout = 0;
switch (mDeviceState)
{
@@ -268,8 +270,7 @@ ThreadError MleRouter::BecomeLeader(void)
router = GetRouter(routerId);
VerifyOrExit(router != NULL, error = kThreadError_NoBufs);
mRouterId = routerId;
mPreviousRouterId = mRouterId;
SetRouterId(routerId);
memcpy(&router->mMacAddr, mMac.GetExtAddress(), sizeof(router->mMacAddr));
@@ -329,32 +330,57 @@ ThreadError MleRouter::HandleChildStart(otMleAttachFilter aFilter)
StopLeader();
mStateUpdateTimer.Start(kStateUpdatePeriod);
mAdvertiseTimer.Start(
Timer::SecToMsec(kReedAdvertiseInterval),
Timer::SecToMsec(kReedAdvertiseInterval + kReedAdvertiseJitter),
TrickleTimer::kModePlainTimer);
mNetif.SubscribeAllRoutersMulticast();
VerifyOrExit(IsRouterIdValid(mPreviousRouterId), ;);
switch (aFilter)
{
case kMleAttachAnyPartition:
break;
case kMleAttachSamePartition:
SendAddressRelease();
// downgrade
if (GetActiveRouterCount() > mRouterDowngradeThreshold)
{
SendAddressRelease();
// reset children info if any
if (HasChildren())
{
RemoveChildren();
}
// reset routerId info
SetRouterId(kInvalidRouterId);
}
else if (HasChildren())
{
BecomeRouter(ThreadStatusTlv::kHaveChildIdRequest);
}
break;
case kMleAttachAnyPartition:
case kMleAttachBetterPartition:
// BecomeRouter();
if (HasChildren() &&
mPreviousPartitionId != mLeaderData.GetPartitionId())
{
BecomeRouter(ThreadStatusTlv::kParentPartitionChange);
}
break;
}
if (mDeviceMode & ModeTlv::kModeFFD)
{
mAdvertiseTimer.Start(
Timer::SecToMsec(kReedAdvertiseInterval),
Timer::SecToMsec(kReedAdvertiseInterval + kReedAdvertiseJitter),
TrickleTimer::kModePlainTimer);
mNetif.SubscribeAllRoutersMulticast();
exit:
if (GetActiveRouterCount() >= mRouterUpgradeThreshold)
{
SendAdvertisement();
}
if (GetActiveRouterCount() >= mRouterUpgradeThreshold &&
(!IsRouterIdValid(mPreviousRouterId) || !HasChildren()))
{
SetRouterId(kInvalidRouterId);
SendAdvertisement();
}
return kThreadError_None;
@@ -374,6 +400,7 @@ ThreadError MleRouter::SetStateRouter(uint16_t aRloc16)
mNetif.SubscribeAllRoutersMulticast();
mRouters[mRouterId].mNextHop = mRouterId;
mPreviousPartitionId = mLeaderData.GetPartitionId();
mNetworkData.Stop();
mStateUpdateTimer.Start(kStateUpdatePeriod);
mNetif.GetIp6().SetForwardingEnabled(true);
@@ -406,6 +433,7 @@ ThreadError MleRouter::SetStateLeader(uint16_t aRloc16)
mNetif.SubscribeAllRoutersMulticast();
mRouters[mRouterId].mNextHop = mRouterId;
mPreviousPartitionId = mLeaderData.GetPartitionId();
mRouters[mRouterId].mLastHeard = Timer::GetNow();
mNetworkData.Start();
@@ -1257,7 +1285,7 @@ ThreadError MleRouter::HandleAdvertisement(const Message &aMessage, const Ip6::M
mLeaderData.GetWeighting(), mLeaderData.GetPartitionId());
if (GetDeviceState() == kDeviceStateChild &&
memcmp(&mParent.mMacAddr, &macAddr, sizeof(mParent.mMacAddr)) == 0)
(memcmp(&mParent.mMacAddr, &macAddr, sizeof(mParent.mMacAddr)) == 0 || !(mDeviceMode & ModeTlv::kModeFFD)))
{
ExitNow();
}
@@ -1693,6 +1721,7 @@ void MleRouter::HandleStateUpdateTimer(void)
{
// upgrade to Router
BecomeRouter(ThreadStatusTlv::kTooFewRouters);
ExitNow();
}
case kDeviceStateRouter:
@@ -3240,9 +3269,15 @@ exit:
return error;
}
void MleRouter::SetPreviousPartitionId(uint32_t aPartitionId)
{
mPreviousPartitionId = aPartitionId;
}
void MleRouter::SetRouterId(uint8_t aRouterId)
{
mRouterId = aRouterId;
mPreviousRouterId = mRouterId;
}
Router *MleRouter::GetRouters(uint8_t *aNumRouters)
@@ -3652,7 +3687,22 @@ void MleRouter::HandleAddressSolicitResponse(Coap::Header *aHeader, Message *aMe
otLogInfoMle("Received address reply");
SuccessOrExit(ThreadTlv::GetTlv(*aMessage, ThreadTlv::kStatus, sizeof(statusTlv), statusTlv));
VerifyOrExit(statusTlv.IsValid() && statusTlv.GetStatus() == statusTlv.kSuccess, ;);
VerifyOrExit(statusTlv.IsValid(), ;);
if (statusTlv.GetStatus() != statusTlv.kSuccess)
{
if (IsRouterIdValid(mPreviousRouterId))
{
if (HasChildren())
{
RemoveChildren();
}
SetRouterId(kInvalidRouterId);
}
ExitNow();
}
SuccessOrExit(ThreadTlv::GetTlv(*aMessage, ThreadTlv::kRloc16, sizeof(rlocTlv), rlocTlv));
VerifyOrExit(rlocTlv.IsValid(), ;);
@@ -3661,10 +3711,21 @@ void MleRouter::HandleAddressSolicitResponse(Coap::Header *aHeader, Message *aMe
SuccessOrExit(ThreadTlv::GetTlv(*aMessage, ThreadTlv::kRouterMask, sizeof(routerMaskTlv), routerMaskTlv));
VerifyOrExit(routerMaskTlv.IsValid(), ;);
// if allocated routerId is different from previous routerId
if (IsRouterIdValid(mPreviousRouterId) && routerId != mPreviousRouterId)
{
// reset children info if any
if (HasChildren())
{
RemoveChildren();
}
}
// assign short address
mRouterId = routerId;
mPreviousRouterId = mRouterId;
SetRouterId(routerId);
SuccessOrExit(SetStateRouter(GetRloc16(mRouterId)));
mRouters[mRouterId].mCost = 0;
// copy router id information
@@ -3691,10 +3752,6 @@ void MleRouter::HandleAddressSolicitResponse(Coap::Header *aHeader, Message *aMe
{
switch (mChildren[i].mState)
{
case Neighbor::kStateInvalid:
case Neighbor::kStateParentRequest:
break;
case Neighbor::kStateChildIdRequest:
SendChildIdResponse(&mChildren[i]);
break;
@@ -3703,14 +3760,11 @@ void MleRouter::HandleAddressSolicitResponse(Coap::Header *aHeader, Message *aMe
assert(false);
break;
case Neighbor::kStateInvalid:
case Neighbor::kStateParentRequest:
case Neighbor::kStateValid:
case Neighbor::kStateRestored:
case Neighbor::kStateChildUpdateRequest:
if (GetRouterId(mChildren[i].mValid.mRloc16) != mRouterId)
{
RemoveNeighbor(mChildren[i]);
}
break;
}
}
@@ -3765,6 +3819,7 @@ void MleRouter::HandleAddressSolicit(Coap::Header &aHeader, Message &aMessage, c
break;
case ThreadStatusTlv::kHaveChildIdRequest:
case ThreadStatusTlv::kParentPartitionChange:
break;
default:
@@ -4280,20 +4335,47 @@ exit:
return rval;
}
bool MleRouter::HasChildren(void)
{
bool hasChildren = false;
for (uint8_t i = 0; i < mMaxChildrenAllowed; i++)
{
if (mChildren[i].mState == Neighbor::kStateRestored || mChildren[i].mState >= Neighbor::kStateChildIdRequest)
{
ExitNow(hasChildren = true);
}
}
exit:
return hasChildren;
}
void MleRouter::RemoveChildren(void)
{
for (uint8_t i = 0; i < mMaxChildrenAllowed; i++)
{
if (mChildren[i].mState == Neighbor::kStateRestored ||
mChildren[i].mState == Neighbor::kStateChildUpdateRequest ||
mChildren[i].mState == Neighbor::kStateValid)
{
RemoveStoredChild(mChildren[i].mValid.mRloc16);
}
mChildren[i].mState = Neighbor::kStateInvalid;
}
}
bool MleRouter::HasSmallNumberOfChildren(void)
{
Child *children;
uint8_t maxChildCount = 0;
uint8_t numChildren = 0;
uint8_t routerCount = GetActiveRouterCount();
VerifyOrExit(routerCount > mRouterDowngradeThreshold, ;);
children = GetChildren(&maxChildCount);
for (uint8_t i = 0; i < maxChildCount; i++)
for (uint8_t i = 0; i < mMaxChildrenAllowed; i++)
{
if (children[i].mState == Neighbor::kStateValid)
if (mChildren[i].mState == Neighbor::kStateValid)
{
numChildren++;
}
+12 -1
View File
@@ -299,7 +299,15 @@ public:
ThreadError SetPreferredRouterId(uint8_t aRouterId);
/**
* This method sets the Router Id from the stored network information.
* This method sets the Partition Id which the device joins successfully.
*
* @param[in] aPartitionId The Partition Id.
*
*/
void SetPreviousPartitionId(uint32_t aPartitionId);
/**
* This method sets the Router Id.
*
* @param[in] aRouterId The Router Id.
*
@@ -764,6 +772,8 @@ private:
Child *FindChild(uint16_t aChildId);
Child *FindChild(const Mac::ExtAddress &aMacAddr);
bool HasChildren(void);
void RemoveChildren(void);
bool HasMinDowngradeNeighborRouters(void);
bool HasOneNeighborwithComparableConnectivity(const RouteTlv &aRoute, uint8_t aRouterId);
bool HasSmallNumberOfChildren(void);
@@ -812,6 +822,7 @@ private:
uint8_t mRouterId;
uint8_t mPreviousRouterId;
uint32_t mPreviousPartitionId;
Coap::Server &mCoapServer;
Coap::Client &mCoapClient;
+1
View File
@@ -69,6 +69,7 @@ public:
void SetLeaderPartitionId(uint32_t) { }
ThreadError SetPreferredRouterId(uint8_t) { return kThreadError_NotImplemented; }
void SetPreviousPartitionId(uint32_t) { }
void SetRouterId(uint8_t) { }
uint16_t GetNextHop(uint16_t aDestination) const { return Mle::GetNextHop(aDestination); }
+1
View File
@@ -329,6 +329,7 @@ public:
kNoAddressAvailable = 1, ///< No address available.
kTooFewRouters = 2, ///< Address Solicit due to too few routers.
kHaveChildIdRequest = 3, ///< Address Solicit due to child ID request.
kParentPartitionChange = 4, ///< Address Solicit due to parent partition change
};
/**
+2 -1
View File
@@ -2485,7 +2485,8 @@ class ARM(IThci):
"""force update to router as if there is child id request"""
print '%s call updateRouterStatus' % self.port
cmd = 'state'
while state = self.__sendCommand(cmd)[0]:
while True:
state = self.__sendCommand(cmd)[0]
if state == 'detached':
continue
elif state == 'child':