mirror of
https://github.com/espressif/openthread.git
synced 2026-08-08 03:37:46 +00:00
Parent keeps restoring children until success or timeout (#1581)
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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));
|
||||
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -93,7 +93,6 @@ public:
|
||||
switch (mState) {
|
||||
case kStateValid:
|
||||
case kStateRestored:
|
||||
case kStateChildUpdateRequest:
|
||||
return true;
|
||||
|
||||
default:
|
||||
|
||||
Reference in New Issue
Block a user