mirror of
https://github.com/espressif/openthread.git
synced 2026-09-12 20:20:04 +00:00
[network-data] synchronize 6LoWPAN Contexts after Leader is reset (#3353)
This commit is contained in:
committed by
Jonathan Hui
parent
7b160157f8
commit
6023df3a3f
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user