mirror of
https://github.com/espressif/openthread.git
synced 2026-10-04 14:57:38 +00:00
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:
+12
-12
@@ -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)
|
||||
|
||||
@@ -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
@@ -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++;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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); }
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -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':
|
||||
|
||||
Reference in New Issue
Block a user