mirror of
https://github.com/espressif/openthread.git
synced 2026-09-17 14:40:07 +00:00
Dynamic Max Children (#462)
* Add support for dynamically adjusting the maximum number of allowed children. * Update cli to support max number of children.
This commit is contained in:
@@ -371,6 +371,26 @@ uint8_t otGetChannel(void);
|
||||
*/
|
||||
ThreadError otSetChannel(uint8_t aChannel);
|
||||
|
||||
/**
|
||||
* Get the maximum number of children currently allowed.
|
||||
*
|
||||
* @returns The maximum number of children currently allowed.
|
||||
*
|
||||
* @sa otSetMaxAllowedChildren
|
||||
*/
|
||||
uint8_t otGetMaxAllowedChildren(void);
|
||||
|
||||
/**
|
||||
* Set the maximum number of children currently allowed.
|
||||
*
|
||||
* @retval kThreadErrorNone Successfully set the max.
|
||||
* @retval kThreadError_InvalidArgs If @p aMaxChildren is not in the range [1, OPENTHREAD_CONFIG_MAX_CHILDREN].
|
||||
* @retval kThreadError_InvalidState If Thread has already been started.
|
||||
*
|
||||
* @sa otGetMaxAllowedChildren
|
||||
*/
|
||||
ThreadError otSetMaxAllowedChildren(uint8_t aMaxChildren);
|
||||
|
||||
/**
|
||||
* Get the Thread Child Timeout used when operating in the Child role.
|
||||
*
|
||||
|
||||
@@ -10,6 +10,7 @@ OpenThread test scripts use the CLI to execute test cases.
|
||||
* [channel](#channel)
|
||||
* [blacklist](#blacklist)
|
||||
* [child](#child)
|
||||
* [childmax](#childmax)
|
||||
* [childtimeout](#childtimeout)
|
||||
* [contextreusedelay](#contextreusedelay)
|
||||
* [counter](#counter)
|
||||
@@ -154,6 +155,25 @@ RSSI: -20
|
||||
Done
|
||||
```
|
||||
|
||||
### childmax
|
||||
|
||||
Get the Thread maximum number of allowed children.
|
||||
|
||||
```bash
|
||||
> childmax
|
||||
5
|
||||
Done
|
||||
```
|
||||
|
||||
### childmax \<count\>
|
||||
|
||||
Set the Thread maximum number of allowed children.
|
||||
|
||||
```bash
|
||||
> childmax 2
|
||||
Done
|
||||
```
|
||||
|
||||
### childtimeout
|
||||
|
||||
Get the Thread Child Timeout value.
|
||||
|
||||
@@ -57,6 +57,7 @@ const struct Command Interpreter::sCommands[] =
|
||||
{ "blacklist", &ProcessBlacklist },
|
||||
{ "channel", &ProcessChannel },
|
||||
{ "child", &ProcessChild },
|
||||
{ "childmax", &ProcessChildMax },
|
||||
{ "childtimeout", &ProcessChildTimeout },
|
||||
{ "contextreusedelay", &ProcessContextIdReuseDelay },
|
||||
{ "counter", &ProcessCounters },
|
||||
@@ -380,6 +381,25 @@ exit:
|
||||
AppendResult(error);
|
||||
}
|
||||
|
||||
void Interpreter::ProcessChildMax(int argc, char *argv[])
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
long value;
|
||||
|
||||
if (argc == 0)
|
||||
{
|
||||
sServer->OutputFormat("%d\r\n", otGetMaxAllowedChildren());
|
||||
}
|
||||
else
|
||||
{
|
||||
SuccessOrExit(error = ParseLong(argv[0], value));
|
||||
SuccessOrExit(error = otSetMaxAllowedChildren(static_cast<uint8_t>(value)));
|
||||
}
|
||||
|
||||
exit:
|
||||
AppendResult(error);
|
||||
}
|
||||
|
||||
void Interpreter::ProcessChildTimeout(int argc, char *argv[])
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
|
||||
@@ -134,6 +134,7 @@ private:
|
||||
static void ProcessChannel(int argc, char *argv[]);
|
||||
static void ProcessChild(int argc, char *argv[]);
|
||||
static void ProcessChildTimeout(int argc, char *argv[]);
|
||||
static void ProcessChildMax(int argc, char *argv[]);
|
||||
static void ProcessContextIdReuseDelay(int argc, char *argv[]);
|
||||
static void ProcessCounters(int argc, char *argv[]);
|
||||
static void ProcessDataset(int argc, char *argv[]);
|
||||
|
||||
@@ -94,6 +94,20 @@ ThreadError otSetChannel(uint8_t aChannel)
|
||||
return sThreadNetif->GetMac().SetChannel(aChannel);
|
||||
}
|
||||
|
||||
uint8_t otGetMaxAllowedChildren(void)
|
||||
{
|
||||
uint8_t aNumChildren;
|
||||
|
||||
(void)sThreadNetif->GetMle().GetChildren(&aNumChildren);
|
||||
|
||||
return aNumChildren;
|
||||
}
|
||||
|
||||
ThreadError otSetMaxAllowedChildren(uint8_t aMaxChildren)
|
||||
{
|
||||
return sThreadNetif->GetMle().SetMaxAllowedChildren(aMaxChildren);
|
||||
}
|
||||
|
||||
uint32_t otGetChildTimeout(void)
|
||||
{
|
||||
return sThreadNetif->GetMle().GetTimeout();
|
||||
|
||||
@@ -481,7 +481,7 @@ void AddressResolver::HandleAddressError(Coap::Header &aHeader, Message &aMessag
|
||||
memcpy(&macAddr, mlIidTlv.GetIid(), sizeof(macAddr));
|
||||
macAddr.m8[0] ^= 0x2;
|
||||
|
||||
for (int i = 0; i < Mle::kMaxChildren; i++)
|
||||
for (int i = 0; i < numChildren; i++)
|
||||
{
|
||||
if (children[i].mState != Neighbor::kStateValid || (children[i].mMode & Mle::ModeTlv::kModeFFD) != 0)
|
||||
{
|
||||
@@ -547,7 +547,7 @@ void AddressResolver::HandleAddressQuery(Coap::Header &aHeader, Message &aMessag
|
||||
|
||||
children = mMle.GetChildren(&numChildren);
|
||||
|
||||
for (int i = 0; i < Mle::kMaxChildren; i++)
|
||||
for (int i = 0; i < numChildren; i++)
|
||||
{
|
||||
if (children[i].mState != Neighbor::kStateValid || (children[i].mMode & Mle::ModeTlv::kModeFFD) != 0)
|
||||
{
|
||||
|
||||
@@ -65,6 +65,7 @@ MleRouter::MleRouter(ThreadNetif &aThreadNetif):
|
||||
mRouterUpgradeThreshold = kRouterUpgradeThreshold;
|
||||
mLeaderWeight = kLeaderWeight;
|
||||
mFixedLeaderPartitionId = 0;
|
||||
mMaxChildrenAllowed = kMaxChildren;
|
||||
mRouterId = kMaxRouterId;
|
||||
mPreviousRouterId = kMaxRouterId;
|
||||
mAdvertiseInterval = kAdvertiseIntervalMin;
|
||||
@@ -986,7 +987,7 @@ ThreadError MleRouter::HandleLinkReject(const Message &aMessage, const Ip6::Mess
|
||||
|
||||
Child *MleRouter::NewChild(void)
|
||||
{
|
||||
for (int i = 0; i < kMaxChildren; i++)
|
||||
for (int i = 0; i < mMaxChildrenAllowed; i++)
|
||||
{
|
||||
if (mChildren[i].mState == Neighbor::kStateInvalid)
|
||||
{
|
||||
@@ -1001,7 +1002,7 @@ Child *MleRouter::FindChild(uint16_t aChildId)
|
||||
{
|
||||
Child *rval = NULL;
|
||||
|
||||
for (int i = 0; i < kMaxChildren; i++)
|
||||
for (int i = 0; i < mMaxChildrenAllowed; i++)
|
||||
{
|
||||
if (mChildren[i].mState != Neighbor::kStateInvalid &&
|
||||
GetChildId(mChildren[i].mValid.mRloc16) == aChildId)
|
||||
@@ -1018,7 +1019,7 @@ Child *MleRouter::FindChild(const Mac::ExtAddress &aAddress)
|
||||
{
|
||||
Child *rval = NULL;
|
||||
|
||||
for (int i = 0; i < kMaxChildren; i++)
|
||||
for (int i = 0; i < mMaxChildrenAllowed; i++)
|
||||
{
|
||||
if (mChildren[i].mState != Neighbor::kStateInvalid &&
|
||||
memcmp(&mChildren[i].mMacAddr, &aAddress, sizeof(mChildren[i].mMacAddr)) == 0)
|
||||
@@ -1140,7 +1141,7 @@ bool MleRouter::IsSingleton(void)
|
||||
}
|
||||
|
||||
// not a singleton if any children are REEDs
|
||||
for (int i = 0; i < kMaxChildren; i++)
|
||||
for (int i = 0; i < mMaxChildrenAllowed; i++)
|
||||
{
|
||||
if (mChildren[i].mState == Neighbor::kStateValid && (mChildren[i].mMode & ModeTlv::kModeFFD))
|
||||
{
|
||||
@@ -1599,7 +1600,7 @@ void MleRouter::HandleStateUpdateTimer(void)
|
||||
}
|
||||
|
||||
// update children state
|
||||
for (int i = 0; i < kMaxChildren; i++)
|
||||
for (int i = 0; i < mMaxChildrenAllowed; i++)
|
||||
{
|
||||
if (mChildren[i].mState == Neighbor::kStateInvalid)
|
||||
{
|
||||
@@ -2227,7 +2228,7 @@ exit:
|
||||
|
||||
Child *MleRouter::GetChild(uint16_t aAddress)
|
||||
{
|
||||
for (int i = 0; i < kMaxChildren; i++)
|
||||
for (int i = 0; i < mMaxChildrenAllowed; i++)
|
||||
{
|
||||
if (mChildren[i].mState == Neighbor::kStateValid && mChildren[i].mValid.mRloc16 == aAddress)
|
||||
{
|
||||
@@ -2240,7 +2241,7 @@ Child *MleRouter::GetChild(uint16_t aAddress)
|
||||
|
||||
Child *MleRouter::GetChild(const Mac::ExtAddress &aAddress)
|
||||
{
|
||||
for (int i = 0; i < kMaxChildren; i++)
|
||||
for (int i = 0; i < mMaxChildrenAllowed; i++)
|
||||
{
|
||||
if (mChildren[i].mState == Neighbor::kStateValid &&
|
||||
memcmp(&mChildren[i].mMacAddr, &aAddress, sizeof(mChildren[i].mMacAddr)) == 0)
|
||||
@@ -2275,12 +2276,29 @@ Child *MleRouter::GetChildren(uint8_t *numChildren)
|
||||
{
|
||||
if (numChildren != NULL)
|
||||
{
|
||||
*numChildren = kMaxChildren;
|
||||
*numChildren = mMaxChildrenAllowed;
|
||||
}
|
||||
|
||||
return mChildren;
|
||||
}
|
||||
|
||||
ThreadError MleRouter::SetMaxAllowedChildren(uint8_t aMaxChildren)
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
|
||||
// Ensure the value is between 1 and kMaxChildren
|
||||
VerifyOrExit(aMaxChildren > 0 && aMaxChildren <= kMaxChildren, error = kThreadError_InvalidArgs);
|
||||
|
||||
// Do not allow setting max children if MLE is running
|
||||
VerifyOrExit(GetDeviceState() == kDeviceStateDisabled, error = kThreadError_InvalidState);
|
||||
|
||||
// Save the value
|
||||
mMaxChildrenAllowed = aMaxChildren;
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
ThreadError MleRouter::RemoveNeighbor(const Mac::Address &aAddress)
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
@@ -2346,7 +2364,7 @@ Neighbor *MleRouter::GetNeighbor(uint16_t aAddress)
|
||||
|
||||
case kDeviceStateRouter:
|
||||
case kDeviceStateLeader:
|
||||
for (int i = 0; i < kMaxChildren; i++)
|
||||
for (int i = 0; i < mMaxChildrenAllowed; i++)
|
||||
{
|
||||
if (mChildren[i].mState == Neighbor::kStateValid && mChildren[i].mValid.mRloc16 == aAddress)
|
||||
{
|
||||
@@ -2385,7 +2403,7 @@ Neighbor *MleRouter::GetNeighbor(const Mac::ExtAddress &aAddress)
|
||||
|
||||
case kDeviceStateRouter:
|
||||
case kDeviceStateLeader:
|
||||
for (int i = 0; i < kMaxChildren; i++)
|
||||
for (int i = 0; i < mMaxChildrenAllowed; i++)
|
||||
{
|
||||
if (mChildren[i].mState == Neighbor::kStateValid &&
|
||||
memcmp(&mChildren[i].mMacAddr, &aAddress, sizeof(mChildren[i].mMacAddr)) == 0)
|
||||
@@ -2462,7 +2480,7 @@ Neighbor *MleRouter::GetNeighbor(const Ip6::Address &aAddress)
|
||||
context.mContextId = 0xff;
|
||||
}
|
||||
|
||||
for (int i = 0; i < kMaxChildren; i++)
|
||||
for (int i = 0; i < mMaxChildrenAllowed; i++)
|
||||
{
|
||||
child = &mChildren[i];
|
||||
|
||||
@@ -2636,7 +2654,7 @@ ThreadError MleRouter::GetChildInfoByIndex(uint8_t aChildIndex, otChildInfo &aCh
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
|
||||
VerifyOrExit(aChildIndex < kMaxChildren, error = kThreadError_InvalidArgs);
|
||||
VerifyOrExit(aChildIndex < mMaxChildrenAllowed, error = kThreadError_InvalidArgs);
|
||||
GetChildInfo(mChildren[aChildIndex], aChildInfo);
|
||||
|
||||
exit:
|
||||
@@ -2909,7 +2927,7 @@ void MleRouter::HandleAddressSolicitResponse(Message &aMessage)
|
||||
ResetAdvertiseInterval();
|
||||
|
||||
// send child id responses
|
||||
for (int i = 0; i < kMaxChildren; i++)
|
||||
for (int i = 0; i < mMaxChildrenAllowed; i++)
|
||||
{
|
||||
switch (mChildren[i].mState)
|
||||
{
|
||||
@@ -3181,7 +3199,7 @@ ThreadError MleRouter::AppendConnectivity(Message &aMessage)
|
||||
|
||||
tlv.Init();
|
||||
|
||||
for (int i = 0; i < kMaxChildren; i++)
|
||||
for (int i = 0; i < mMaxChildrenAllowed; i++)
|
||||
{
|
||||
if (mChildren[i].mState == Neighbor::kStateValid)
|
||||
{
|
||||
@@ -3189,7 +3207,7 @@ ThreadError MleRouter::AppendConnectivity(Message &aMessage)
|
||||
}
|
||||
}
|
||||
|
||||
if ((kMaxChildren - numChildren) < (kMaxChildren / 3))
|
||||
if ((mMaxChildrenAllowed - numChildren) < (mMaxChildrenAllowed / 3))
|
||||
{
|
||||
tlv.SetParentPriority(-1);
|
||||
}
|
||||
|
||||
@@ -316,6 +316,18 @@ public:
|
||||
*/
|
||||
Child *GetChildren(uint8_t *aNumChildren);
|
||||
|
||||
/**
|
||||
* This method sets the max children allowed value for this Thread interface.
|
||||
*
|
||||
* @param[in] aMaxChildren The max children allowed value.
|
||||
*
|
||||
* @retval kThreadErrorNone Successfully set the max.
|
||||
* @retval kThreadError_InvalidArgs If @p aMaxChildren is not in the range [1, kMaxChildren].
|
||||
* @retval kThreadError_InvalidState If MLE has already been started.
|
||||
*
|
||||
*/
|
||||
ThreadError SetMaxAllowedChildren(uint8_t aMaxChildren);
|
||||
|
||||
/**
|
||||
* This method returns a pointer to a Neighbor object.
|
||||
*
|
||||
@@ -528,6 +540,7 @@ private:
|
||||
uint8_t mRouterIdSequence;
|
||||
uint32_t mRouterIdSequenceLastUpdated;
|
||||
Router mRouters[kMaxRouterId];
|
||||
uint8_t mMaxChildrenAllowed;
|
||||
Child mChildren[kMaxChildren];
|
||||
|
||||
uint8_t mChallenge[8];
|
||||
|
||||
Reference in New Issue
Block a user