Parent keeps restoring children until success or timeout (#1581)

This commit is contained in:
rongli
2017-04-13 08:38:53 -07:00
committed by Jonathan Hui
parent c4a4e758c9
commit 7b0bc2a30f
7 changed files with 43 additions and 39 deletions
+1
View File
@@ -361,6 +361,7 @@ bool Message::IsSubTypeMle(void) const
if (mInfo.mSubType == kSubTypeMleAnnounce ||
mInfo.mSubType == kSubTypeMleDiscoverRequest ||
mInfo.mSubType == kSubTypeMleDiscoverResponse ||
mInfo.mSubType == kSubTypeMleChildUpdateRequest ||
mInfo.mSubType == kSubTypeMleGeneral)
{
rval = true;
+2 -1
View File
@@ -110,7 +110,7 @@ struct MessageInfo
};
uint8_t mType : 2; ///< Identifies the type of message.
uint8_t mSubType : 3; ///< Identifies the message sub type.
uint8_t mSubType : 4; ///< Identifies the message sub type.
bool mDirectTx : 1; ///< Used to indicate whether a direct transmission is required.
bool mLinkSecurity : 1; ///< Indicates whether or not link security is enabled.
uint8_t mPriority : 2; ///< Identifies the message priority level (lower value is higher priority).
@@ -218,6 +218,7 @@ public:
kSubTypeMplRetransmission = 5, ///< MPL next retranmission message
kSubTypeMleGeneral = 6, ///< General MLE
kSubTypeJoinerFinalizeResponse = 7, ///< Joiner Finalize Response
kSubTypeMleChildUpdateRequest = 8, ///< MLE Child Update Request
};
enum
+1
View File
@@ -1672,6 +1672,7 @@ ThreadError Mle::SendChildUpdateRequest(void)
mChildUpdateAttempts++;
VerifyOrExit((message = NewMleMessage()) != NULL);
message->SetSubType(Message::kSubTypeMleChildUpdateRequest);
SuccessOrExit(error = AppendHeader(*message, Header::kCommandChildUpdateRequest));
SuccessOrExit(error = AppendMode(*message, mDeviceMode));
-1
View File
@@ -64,7 +64,6 @@ enum
kUnicastRetransmissionDelay = 1000, ///< Base delay before retransmitting an MLE unicast.
kMaxResponseDelay = 1000, ///< Maximum delay before responding to a multicast request
kMaxChildIdRequestTimeout = 5000, ///< Maximum delay for receiving a Child ID Request
kChildUpdateRequestPeriod = 100, ///< The period for sending Child Update Request
kMaxChildUpdateResponseTimeout = 2000, ///< Maximum delay for receiving a Child Update Response
};
+38 -33
View File
@@ -56,7 +56,6 @@ MleRouter::MleRouter(ThreadNetif &aThreadNetif):
Mle(aThreadNetif),
mAdvertiseTimer(aThreadNetif.GetIp6().mTimerScheduler, &MleRouter::HandleAdvertiseTimer, NULL, this),
mStateUpdateTimer(aThreadNetif.GetIp6().mTimerScheduler, &MleRouter::HandleStateUpdateTimer, this),
mChildUpdateRequestTimer(aThreadNetif.GetIp6().mTimerScheduler, &MleRouter::HandleChildUpdateRequestTimer, this),
mAddressSolicit(OPENTHREAD_URI_ADDRESS_SOLICIT, &MleRouter::HandleAddressSolicit, this),
mAddressRelease(OPENTHREAD_URI_ADDRESS_RELEASE, &MleRouter::HandleAddressRelease, this)
{
@@ -74,6 +73,7 @@ MleRouter::MleRouter(ThreadNetif &aThreadNetif):
mLeaderWeight = kLeaderWeight;
mFixedLeaderPartitionId = 0;
mMaxChildrenAllowed = kMaxChildren;
mIsRouterRestoringChildren = false;
SetRouterId(kInvalidRouterId);
mPreviousPartitionId = 0;
@@ -406,7 +406,7 @@ ThreadError MleRouter::SetStateRouter(uint16_t aRloc16)
{
if (mChildren[i].GetState() == Neighbor::kStateRestored)
{
mChildUpdateRequestTimer.Start(kChildUpdateRequestPeriod);
mIsRouterRestoringChildren = true;
break;
}
}
@@ -447,7 +447,7 @@ ThreadError MleRouter::SetStateLeader(uint16_t aRloc16)
{
if (mChildren[i].GetState() == Neighbor::kStateRestored)
{
mChildUpdateRequestTimer.Start(kChildUpdateRequestPeriod);
mIsRouterRestoringChildren = true;
break;
}
}
@@ -1766,6 +1766,26 @@ void MleRouter::HandleStateUpdateTimer(void)
break;
}
if (mIsRouterRestoringChildren)
{
bool hasRestoringChildren = false;
for (uint8_t i = 0; i < mMaxChildrenAllowed; i++)
{
if (mChildren[i].GetState() == Neighbor::kStateRestored)
{
SendChildUpdateRequest(&mChildren[i]);
hasRestoringChildren = true;
}
}
// no child to restore
if (!hasRestoringChildren)
{
mIsRouterRestoringChildren = false;
}
}
// update children state
for (int i = 0; i < mMaxChildrenAllowed; i++)
{
@@ -1834,36 +1854,6 @@ exit:
return;
}
void MleRouter::HandleChildUpdateRequestTimer(void *aContext)
{
static_cast<MleRouter *>(aContext)->HandleChildUpdateRequestTimer();
}
void MleRouter::HandleChildUpdateRequestTimer(void)
{
VerifyOrExit(GetDeviceState() == kDeviceStateRouter || GetDeviceState() == kDeviceStateLeader);
for (int i = 0; i < mMaxChildrenAllowed; i++)
{
if (mChildren[i].GetState() == Neighbor::kStateRestored)
{
SendChildUpdateRequest(&mChildren[i]);
mChildren[i].SetState(Neighbor::kStateChildUpdateRequest);
if (mChildren[i].IsRxOnWhenIdle())
{
mChildren[i].SetTimeout(Timer::MsecToSec(kMaxChildUpdateResponseTimeout));
}
mChildUpdateRequestTimer.Start(kChildUpdateRequestPeriod);
break;
}
}
exit:
return;
}
ThreadError MleRouter::SendParentResponse(Child *aChild, const ChallengeTlv &challenge, bool aRoutersOnlyRequest)
{
ThreadError error = kThreadError_None;
@@ -2679,7 +2669,22 @@ ThreadError MleRouter::SendChildUpdateRequest(Child *aChild)
Ip6::Address destination;
Message *message;
if (!aChild->IsRxOnWhenIdle())
{
uint8_t childIndex = mNetif.GetMle().GetChildIndex(*aChild);
// No need to send "Child Update Request" to the sleepy child if there is one already queued for it.
for (message = mNetif.GetMeshForwarder().GetSendQueue().GetHead(); message; message = message->GetNext())
{
if (message->GetChildMask(childIndex) && message->GetSubType() == Message::kSubTypeMleChildUpdateRequest)
{
ExitNow();
}
}
}
VerifyOrExit((message = NewMleMessage()) != NULL);
message->SetSubType(Message::kSubTypeMleChildUpdateRequest);
SuccessOrExit(error = AppendHeader(*message, Header::kCommandChildUpdateRequest));
SuccessOrExit(error = AppendSourceAddress(*message));
SuccessOrExit(error = AppendLeaderData(*message));
+1 -3
View File
@@ -718,12 +718,9 @@ private:
bool HandleAdvertiseTimer(void);
static void HandleStateUpdateTimer(void *aContext);
void HandleStateUpdateTimer(void);
static void HandleChildUpdateRequestTimer(void *aContext);
void HandleChildUpdateRequestTimer(void);
TrickleTimer mAdvertiseTimer;
Timer mStateUpdateTimer;
Timer mChildUpdateRequestTimer;
Coap::Resource mAddressSolicit;
Coap::Resource mAddressRelease;
@@ -743,6 +740,7 @@ private:
uint8_t mLeaderWeight;
uint32_t mFixedLeaderPartitionId; ///< only for certification testing
bool mRouterRoleEnabled;
bool mIsRouterRestoringChildren;
uint8_t mRouterId;
uint8_t mPreviousRouterId;
-1
View File
@@ -93,7 +93,6 @@ public:
switch (mState) {
case kStateValid:
case kStateRestored:
case kStateChildUpdateRequest:
return true;
default: