Implement ROUTER_DOWNGRADE_THRESHOLD. (#588)

This commit is contained in:
Xiao Ma
2016-09-14 09:25:56 -07:00
committed by Jonathan Hui
parent ef2a1a0c9d
commit a642297520
7 changed files with 265 additions and 0 deletions
+18
View File
@@ -1492,6 +1492,24 @@ void otSetAssignLinkQuality(otInstance *aInstance, const uint8_t *aExtAddr, uint
*/
void otPlatformReset(otInstance *aInstance);
/**
* Get the ROUTER_DOWNGRADE_THRESHOLD parameter used in the Router role.
*
* @returns The ROUTER_DOWNGRADE_THRESHOLD value.
*
* @sa otSetRouterDowngradeThreshold
*/
uint8_t otGetRouterDowngradeThreshold(void);
/**
* Set the ROUTER_DOWNGRADE_THRESHOLD parameter used in the Leader role.
*
* @param[in] aThreshold The ROUTER_DOWNGRADE_THRESHOLD value.
*
* @sa otGetRouterDowngradeThreshold
*/
void otSetRouterDowngradeThreshold(uint8_t aThreshold);
/**
* @}
*
+20
View File
@@ -41,6 +41,7 @@ OpenThread test scripts use the CLI to execute test cases.
* [rloc16](#rloc16)
* [route](#route)
* [router](#router)
* [routerdowngradethreshold](#routerdowngradethreshold)
* [routerrole](#routerrole)
* [routerupgradethreshold](#routerupgradethreshold)
* [scan](#scan)
@@ -1023,6 +1024,25 @@ Age: 7
Done
```
### routerdowngradethreshold
Get the ROUTER_DOWNGRADE_THRESHOLD value.
```bash
> routerdowngradethreshold
23
Done
```
### routerdowngradethreshold \<threshold\>
Set the ROUTER_DOWNGRADE_THRESHOLD value.
```bash
> routerdowngradethreshold 23
Done
```
### routerrole
Indicates whether the router role is enabled or disabled.
+20
View File
@@ -116,6 +116,7 @@ const struct Command Interpreter::sCommands[] =
{ "rloc16", &Interpreter::ProcessRloc16 },
{ "route", &Interpreter::ProcessRoute },
{ "router", &Interpreter::ProcessRouter },
{ "routerdowngradethreshold", &Interpreter::ProcessRouterDowngradeThreshold },
{ "routerrole", &Interpreter::ProcessRouterRole },
{ "routerupgradethreshold", &Interpreter::ProcessRouterUpgradeThreshold },
{ "scan", &Interpreter::ProcessScan },
@@ -1657,6 +1658,25 @@ exit:
AppendResult(error);
}
void Interpreter::ProcessRouterDowngradeThreshold(int argc, char *argv[])
{
ThreadError error = kThreadError_None;
long value;
if (argc == 0)
{
sServer->OutputFormat("%d\r\n", otGetRouterDowngradeThreshold());
}
else
{
SuccessOrExit(error = ParseLong(argv[0], value));
otSetRouterDowngradeThreshold(static_cast<uint8_t>(value));
}
exit:
AppendResult(error);
}
void Interpreter::ProcessRouterRole(int argc, char *argv[])
{
ThreadError error = kThreadError_None;
+1
View File
@@ -189,6 +189,7 @@ private:
void ProcessReset(int argc, char *argv[]);
void ProcessRoute(int argc, char *argv[]);
void ProcessRouter(int argc, char *argv[]);
void ProcessRouterDowngradeThreshold(int argc, char *argv[]);
void ProcessRouterRole(int argc, char *argv[]);
ThreadError ProcessRouteAdd(int argc, char *argv[]);
ThreadError ProcessRouteRemove(int argc, char *argv[]);
+10
View File
@@ -663,6 +663,16 @@ void otPlatformReset(otInstance *aInstance)
otPlatReset(aInstance);
}
uint8_t otGetRouterDowngradeThreshold(void)
{
return sThreadNetif->GetMle().GetRouterDowngradeThreshold();
}
void otSetRouterDowngradeThreshold(uint8_t aThreshold)
{
sThreadNetif->GetMle().SetRouterDowngradeThreshold(aThreshold);
}
ThreadError otGetChildInfoById(otInstance *, uint16_t aChildId, otChildInfo *aChildInfo)
{
ThreadError error = kThreadError_None;
+173
View File
@@ -64,6 +64,7 @@ MleRouter::MleRouter(ThreadNetif &aThreadNetif):
mNetworkIdTimeout = kNetworkIdTimeout;
mRouterUpgradeThreshold = kRouterUpgradeThreshold;
mRouterDowngradeThreshold = kRouterDowngradeThreshold;
mLeaderWeight = kLeaderWeight;
mFixedLeaderPartitionId = 0;
mMaxChildrenAllowed = kMaxChildren;
@@ -72,6 +73,7 @@ MleRouter::MleRouter(ThreadNetif &aThreadNetif):
mAdvertiseInterval = kAdvertiseIntervalMin;
mRouterIdSequenceLastUpdated = 0;
mRouterRoleEnabled = true;
mRouterSelectionJitterTimeout = 0;
mCoapMessageId = static_cast<uint8_t>(otPlatRandomGet());
}
@@ -394,6 +396,16 @@ void MleRouter::SetRouterUpgradeThreshold(uint8_t aThreshold)
mRouterUpgradeThreshold = aThreshold;
}
uint8_t MleRouter::GetRouterDowngradeThreshold(void) const
{
return mRouterDowngradeThreshold;
}
void MleRouter::SetRouterDowngradeThreshold(uint8_t aThreshold)
{
mRouterDowngradeThreshold = aThreshold;
}
void MleRouter::HandleAdvertiseTimer(void *aContext)
{
MleRouter *obj = reinterpret_cast<MleRouter *>(aContext);
@@ -1371,6 +1383,28 @@ ThreadError MleRouter::HandleAdvertisement(const Message &aMessage, const Ip6::M
ExitNow();
case kDeviceStateRouter:
// check current active router number
routerCount = 0;
for (uint8_t i = 0; i < kMaxRouterId; i++)
{
if (route.IsRouterIdSet(i))
{
routerCount++;
}
}
if (routerCount > mRouterDowngradeThreshold &&
mRouterSelectionJitterTimeout == 0 &&
HasMinDowngradeNeighborRouters() &&
HasSmallNumberOfChildren() &&
HasOneNeighborwithComparableConnectivity(route, routerId))
{
mRouterSelectionJitterTimeout = otPlatRandomGet() % kRouterSelectionJitter;
}
// fall through
case kDeviceStateLeader:
router = &mRouters[routerId];
@@ -1631,6 +1665,18 @@ void MleRouter::HandleStateUpdateTimer(void)
BecomeChild(kMleAttachSamePartition);
}
if (mRouterSelectionJitterTimeout > 0)
{
mRouterSelectionJitterTimeout--;
if (mRouterSelectionJitterTimeout == 0 &&
GetActiveRouterCount() > mRouterDowngradeThreshold)
{
// downgrade to REED
BecomeChild(kMleAttachSamePartition);
}
}
break;
case kDeviceStateLeader:
@@ -3494,5 +3540,132 @@ exit:
return error;
}
bool MleRouter::HasMinDowngradeNeighborRouters(void)
{
return GetMinDowngradeNeighborRouters() >= kMinDowngradeNeighbors;
}
bool MleRouter::HasOneNeighborwithComparableConnectivity(const RouteTlv &aRoute, uint8_t aRouterId)
{
bool rval = true;
uint8_t localLqi = 0;
uint8_t peerLqi = 0;
uint8_t routerCount = 0;
// process local neighbor routers
for (uint8_t i = 0; i < kMaxRouterId; i++)
{
if (i == mRouterId)
{
routerCount++;
continue;
}
// check if neighbor is valid
if (mRouters[i].mState == Neighbor::kStateValid)
{
// if neighbor is just peer
if (i == aRouterId)
{
routerCount++;
continue;
}
localLqi = mRouters[i].mLinkInfo.GetLinkQuality(mMac.GetNoiseFloor());
if (localLqi > mRouters[i].mLinkQualityOut)
{
localLqi = mRouters[i].mLinkQualityOut;
}
if (localLqi >= 2)
{
// check if this neighbor router is in peer Route64 TLV
if (aRoute.IsRouterIdSet(i) == false)
{
ExitNow(rval = false);
}
// get the peer's two-way lqi to this router
peerLqi = aRoute.GetLinkQualityIn(routerCount);
if (peerLqi > aRoute.GetLinkQualityOut(routerCount))
{
peerLqi = aRoute.GetLinkQualityOut(routerCount);
}
// compare local lqi to this router with peer's
if (peerLqi >= localLqi)
{
routerCount++;
continue;
}
else
{
ExitNow(rval = false);
}
}
routerCount++;
}
}
exit:
return rval;
}
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++)
{
if (children[i].mState == Neighbor::kStateValid)
{
numChildren++;
}
}
return numChildren < (routerCount - mRouterDowngradeThreshold) * 3;
exit:
return false;
}
uint8_t MleRouter::GetMinDowngradeNeighborRouters(void)
{
uint8_t lqi;
uint8_t routerCount = 0;
for (uint8_t i = 0; i < kMaxRouterId; i++)
{
if (mRouters[i].mState != Neighbor::kStateValid)
{
continue;
}
lqi = mRouters[i].mLinkInfo.GetLinkQuality(mMac.GetNoiseFloor());
if (lqi > mRouters[i].mLinkQualityOut)
{
lqi = mRouters[i].mLinkQualityOut;
}
if (lqi >= 2)
{
routerCount++;
}
}
return routerCount;
}
} // namespace Mle
} // namespace Thread
+23
View File
@@ -234,6 +234,22 @@ public:
*/
void SetRouterUpgradeThreshold(uint8_t aThreshold);
/**
* This method returns the ROUTER_DOWNGRADE_THRESHOLD value.
*
* @returns The ROUTER_DOWNGRADE_THRESHOLD value.
*
*/
uint8_t GetRouterDowngradeThreshold(void) const;
/**
* This method sets the ROUTER_DOWNGRADE_THRESHOLD value.
*
* @returns The ROUTER_DOWNGRADE_THRESHOLD value.
*
*/
void SetRouterDowngradeThreshold(uint8_t aThreshold);
/**
* This method release a given Router ID.
*
@@ -521,6 +537,11 @@ private:
Child *FindChild(uint16_t aChildId);
Child *FindChild(const Mac::ExtAddress &aMacAddr);
bool HasMinDowngradeNeighborRouters(void);
bool HasOneNeighborwithComparableConnectivity(const RouteTlv &aRoute, uint8_t aRouterId);
bool HasSmallNumberOfChildren(void);
uint8_t GetMinDowngradeNeighborRouters(void);
uint8_t AllocateRouterId(void);
uint8_t AllocateRouterId(uint8_t aRouterId);
bool InRouterIdMask(uint8_t aRouterId);
@@ -547,9 +568,11 @@ private:
uint16_t mNextChildId;
uint8_t mNetworkIdTimeout;
uint8_t mRouterUpgradeThreshold;
uint8_t mRouterDowngradeThreshold;
uint8_t mLeaderWeight;
uint32_t mFixedLeaderPartitionId; ///< only for certification testing
bool mRouterRoleEnabled;
uint8_t mRouterSelectionJitterTimeout;
uint8_t mRouterId;
uint8_t mPreviousRouterId;