mirror of
https://github.com/espressif/openthread.git
synced 2026-09-12 12:10:07 +00:00
Implement ROUTER_DOWNGRADE_THRESHOLD. (#588)
This commit is contained in:
@@ -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);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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[]);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user