[network-data] synchronize 6LoWPAN Contexts after Leader is reset (#3353)

This commit is contained in:
Łukasz Duda
2018-12-06 08:48:15 -08:00
committed by Jonathan Hui
parent 7b160157f8
commit 6023df3a3f
3 changed files with 76 additions and 12 deletions
+8
View File
@@ -429,6 +429,14 @@ otError LeaderBase::SetNetworkData(uint8_t aVersion,
RemoveTemporaryData(mTlvs, mLength);
}
#if OPENTHREAD_FTD
// Synchronize internal 6LoWPAN Context ID Set with recently obtained Network Data.
if (GetNetif().GetMle().GetRole() == OT_DEVICE_ROLE_LEADER)
{
GetNetif().GetNetworkDataLeader().UpdateContextsAfterReset();
}
#endif
otDumpDebgNetData("set network data", mTlvs, mLength);
GetNotifier().Signal(OT_CHANGED_THREAD_NETDATA);
+55 -10
View File
@@ -1167,7 +1167,7 @@ otError Leader::AddBorderRouter(PrefixTlv &aPrefix, BorderRouterTlv &aBorderRout
}
dstContext->SetCompress();
mContextLastUsed[dstContext->GetContextId() - kMinContextId] = 0;
StopContextReuseTimer(dstContext->GetContextId());
if (dstBorderRouter == NULL)
{
@@ -1224,6 +1224,23 @@ otError Leader::FreeContext(uint8_t aContextId)
return OT_ERROR_NONE;
}
void Leader::StartContextReuseTimer(uint8_t aContextId)
{
mContextLastUsed[aContextId - kMinContextId] = TimerMilli::GetNow();
if (mContextLastUsed[aContextId - kMinContextId] == 0)
{
mContextLastUsed[aContextId - kMinContextId] = 1;
}
mTimer.Start(kStateUpdatePeriod);
}
void Leader::StopContextReuseTimer(uint8_t aContextId)
{
mContextLastUsed[aContextId - kMinContextId] = 0;
}
otError Leader::SendServerDataNotification(uint16_t aRloc16)
{
otError error = OT_ERROR_NONE;
@@ -1362,19 +1379,12 @@ otError Leader::RemoveRloc(PrefixTlv &prefix, uint16_t aRloc16, MatchMode aMatch
if (prefix.GetSubTlvsLength() == sizeof(ContextTlv))
{
context->ClearCompress();
mContextLastUsed[context->GetContextId() - kMinContextId] = TimerMilli::GetNow();
if (mContextLastUsed[context->GetContextId() - kMinContextId] == 0)
{
mContextLastUsed[context->GetContextId() - kMinContextId] = 1;
}
mTimer.Start(kStateUpdatePeriod);
StartContextReuseTimer(context->GetContextId());
}
else
{
context->SetCompress();
mContextLastUsed[context->GetContextId() - kMinContextId] = 0;
StopContextReuseTimer(context->GetContextId());
}
}
@@ -1552,6 +1562,41 @@ otError Leader::RemoveContext(PrefixTlv &aPrefix, uint8_t aContextId)
return OT_ERROR_NONE;
}
void Leader::UpdateContextsAfterReset(void)
{
PrefixTlv * prefix;
ContextTlv *contextTlv;
// Iterate through Network Data and synchronize missing contexts.
for (NetworkDataTlv *cur = reinterpret_cast<NetworkDataTlv *>(mTlvs);
cur < reinterpret_cast<NetworkDataTlv *>(mTlvs + mLength); cur = cur->GetNext())
{
if (cur->GetType() != NetworkDataTlv::kTypePrefix)
{
continue;
}
prefix = static_cast<PrefixTlv *>(cur);
contextTlv = FindContext(*prefix);
if (contextTlv == NULL)
{
continue;
}
mContextUsed |= 1 << contextTlv->GetContextId();
if (contextTlv->IsCompress())
{
StopContextReuseTimer(contextTlv->GetContextId());
}
else
{
StartContextReuseTimer(contextTlv->GetContextId());
}
}
}
void Leader::HandleTimer(Timer &aTimer)
{
aTimer.GetOwner<Leader>().HandleTimer();
+13 -2
View File
@@ -151,6 +151,14 @@ public:
*/
otError SendServerDataNotification(uint16_t aRloc16);
/**
* This method synchronizes internal 6LoWPAN Context ID Set with recently obtained Thread Network Data.
*
* Note that this method should be called only by the Leader once after reset.
*
*/
void UpdateContextsAfterReset(void);
#if OPENTHREAD_ENABLE_SERVICE
/**
* This method scans network data for given service ID and returns pointer to the respective TLV, if present.
@@ -185,6 +193,8 @@ private:
int AllocateContext(void);
otError FreeContext(uint8_t aContextId);
void StartContextReuseTimer(uint8_t aContextId);
void StopContextReuseTimer(uint8_t aContextId);
otError RemoveContext(uint8_t aContextId);
otError RemoveContext(PrefixTlv &aPrefix, uint8_t aContextId);
@@ -232,7 +242,7 @@ private:
MeshCoP::StateTlv::State aState);
/**
* Thread Specification Constants
* Thread Specification Constants.
*
*/
enum
@@ -240,8 +250,9 @@ private:
kMinContextId = 1, ///< Minimum Context ID (0 is used for Mesh Local)
kNumContextIds = 15, ///< Maximum Context ID
kContextIdReuseDelay = 48 * 60 * 60, ///< CONTEXT_ID_REUSE_DELAY (seconds)
kStateUpdatePeriod = 1000, ///< State update period in milliseconds
kStateUpdatePeriod = 60 * 1000, ///< State update period in milliseconds
};
uint16_t mContextUsed;
uint32_t mContextLastUsed[kNumContextIds];
uint32_t mContextIdReuseDelay;