Automatically update leader with network data. (#480)

This commit is contained in:
Jonathan Hui
2016-08-31 19:58:19 -07:00
committed by GitHub
parent 545ed64c47
commit 55d53b627c
6 changed files with 239 additions and 6 deletions
+2
View File
@@ -961,6 +961,8 @@ void Mle::HandleNetifStateChanged(uint32_t aFlags)
{
mSendChildUpdateRequest.Post();
}
mNetif.GetNetworkDataLocal().SendServerDataNotification();
}
}
+2
View File
@@ -1369,6 +1369,8 @@ ThreadError MleRouter::HandleAdvertisement(const Message &aMessage, const Ip6::M
UpdateRoutes(route, routerId);
mNetif.GetNetworkDataLocal().SendServerDataNotification();
exit:
return error;
}
+141 -3
View File
@@ -66,6 +66,12 @@ void NetworkData::GetNetworkData(bool aStable, uint8_t *aData, uint8_t &aDataLen
}
ThreadError NetworkData::GetNextOnMeshPrefix(otNetworkDataIterator *aIterator, otBorderRouterConfig *aConfig)
{
return GetNextOnMeshPrefix(aIterator, Mac::kShortAddrBroadcast, aConfig);
}
ThreadError NetworkData::GetNextOnMeshPrefix(otNetworkDataIterator *aIterator, uint16_t aRloc16,
otBorderRouterConfig *aConfig)
{
ThreadError error = kThreadError_NotFound;
NetworkDataTlv *cur = reinterpret_cast<NetworkDataTlv *>(mTlvs + *aIterator);
@@ -75,7 +81,7 @@ ThreadError NetworkData::GetNextOnMeshPrefix(otNetworkDataIterator *aIterator, o
{
PrefixTlv *prefix;
BorderRouterTlv *borderRouter;
BorderRouterEntry *borderRouterEntry;
BorderRouterEntry *borderRouterEntry = NULL;
if (cur->GetType() != NetworkDataTlv::kTypePrefix)
{
@@ -89,9 +95,22 @@ ThreadError NetworkData::GetNextOnMeshPrefix(otNetworkDataIterator *aIterator, o
continue;
}
borderRouterEntry = borderRouter->GetEntry(0);
for (uint8_t i = 0; i < borderRouter->GetNumEntries(); i++)
{
if (aRloc16 == Mac::kShortAddrBroadcast || borderRouter->GetEntry(i)->GetRloc() == aRloc16)
{
borderRouterEntry = borderRouter->GetEntry(i);
break;
}
}
memcpy(&aConfig->mPrefix.mPrefix, prefix->GetPrefix(), sizeof(aConfig->mPrefix.mPrefix));
if (borderRouterEntry == NULL)
{
continue;
}
memset(aConfig, 0, sizeof(*aConfig));
memcpy(&aConfig->mPrefix.mPrefix, prefix->GetPrefix(), BitVectorBytes(prefix->GetPrefixLength()));
aConfig->mPrefix.mLength = prefix->GetPrefixLength();
aConfig->mPreference = borderRouterEntry->GetPreference();
aConfig->mPreferred = borderRouterEntry->IsPreferred();
@@ -111,6 +130,125 @@ exit:
return error;
}
ThreadError NetworkData::GetNextExternalRoute(otNetworkDataIterator *aIterator, otExternalRouteConfig *aConfig)
{
return GetNextExternalRoute(aIterator, Mac::kShortAddrBroadcast, aConfig);
}
ThreadError NetworkData::GetNextExternalRoute(otNetworkDataIterator *aIterator, uint16_t aRloc16,
otExternalRouteConfig *aConfig)
{
ThreadError error = kThreadError_NotFound;
NetworkDataTlv *cur = reinterpret_cast<NetworkDataTlv *>(mTlvs + *aIterator);
NetworkDataTlv *end = reinterpret_cast<NetworkDataTlv *>(mTlvs + mLength);
for (; cur < end; cur = cur->GetNext())
{
PrefixTlv *prefix;
HasRouteTlv *hasRoute;
HasRouteEntry *hasRouteEntry = NULL;
if (cur->GetType() != NetworkDataTlv::kTypePrefix)
{
continue;
}
prefix = static_cast<PrefixTlv *>(cur);
if ((hasRoute = FindHasRoute(*prefix)) == NULL)
{
continue;
}
for (uint8_t i = 0; i < hasRoute->GetNumEntries(); i++)
{
if (aRloc16 == Mac::kShortAddrBroadcast || hasRoute->GetEntry(i)->GetRloc() == aRloc16)
{
hasRouteEntry = hasRoute->GetEntry(i);
break;
}
}
if (hasRouteEntry == NULL)
{
continue;
}
memset(aConfig, 0, sizeof(*aConfig));
memcpy(&aConfig->mPrefix.mPrefix, prefix->GetPrefix(), BitVectorBytes(prefix->GetPrefixLength()));
aConfig->mPrefix.mLength = prefix->GetPrefixLength();
aConfig->mPreference = hasRouteEntry->GetPreference();
aConfig->mStable = cur->IsStable();
*aIterator = static_cast<otNetworkDataIterator>(reinterpret_cast<uint8_t *>(cur->GetNext()) - mTlvs);
ExitNow(error = kThreadError_None);
}
exit:
return error;
}
bool NetworkData::ContainsOnMeshPrefixes(NetworkData &aCompare, uint16_t aRloc16)
{
otNetworkDataIterator outerIterator = OT_NETWORK_DATA_ITERATOR_INIT;
otBorderRouterConfig outerConfig;
bool rval = true;
while (aCompare.GetNextOnMeshPrefix(&outerIterator, aRloc16, &outerConfig) == kThreadError_None)
{
otNetworkDataIterator innerIterator = OT_NETWORK_DATA_ITERATOR_INIT;
otBorderRouterConfig innerConfig;
ThreadError error;
while ((error = GetNextOnMeshPrefix(&innerIterator, aRloc16, &innerConfig)) == kThreadError_None)
{
if (memcmp(&outerConfig, &innerConfig, sizeof(outerConfig)) == 0)
{
break;
}
}
if (error != kThreadError_None)
{
ExitNow(rval = false);
}
}
exit:
return rval;
}
bool NetworkData::ContainsExternalRoutes(NetworkData &aCompare, uint16_t aRloc16)
{
otNetworkDataIterator outerIterator = OT_NETWORK_DATA_ITERATOR_INIT;
otExternalRouteConfig outerConfig;
bool rval = true;
while (aCompare.GetNextExternalRoute(&outerIterator, aRloc16, &outerConfig) == kThreadError_None)
{
otNetworkDataIterator innerIterator = OT_NETWORK_DATA_ITERATOR_INIT;
otExternalRouteConfig innerConfig;
ThreadError error;
while ((error = GetNextExternalRoute(&innerIterator, aRloc16, &innerConfig)) == kThreadError_None)
{
if (memcmp(&outerConfig, &innerConfig, sizeof(outerConfig)) == 0)
{
break;
}
}
if (error != kThreadError_None)
{
ExitNow(rval = false);
}
}
exit:
return rval;
}
void NetworkData::RemoveTemporaryData(uint8_t *aData, uint8_t &aDataLength)
{
NetworkDataTlv *cur = reinterpret_cast<NetworkDataTlv *>(aData);
+67 -2
View File
@@ -108,8 +108,8 @@ public:
/**
* This method provides the next On Mesh prefix in the Thread Network Data.
*
* @param[out] aIterator A pointer to the Network Data iterator context.
* @param[out] aConfig A pointer to where the On Mesh Prefix information will be placed.
* @param[inout] aIterator A pointer to the Network Data iterator context.
* @param[out] aConfig A pointer to where the On Mesh Prefix information will be placed.
*
* @retval kThreadError_None Successfully found the next On Mesh prefix.
* @retval kThreadError_NotFound No subsequent On Mesh prefix exists in the Thread Network Data.
@@ -117,6 +117,71 @@ public:
*/
ThreadError GetNextOnMeshPrefix(otNetworkDataIterator *aIterator, otBorderRouterConfig *aConfig);
/**
* This method provides the next On Mesh prefix in the Thread Network Data for a given RLOC16.
*
* @param[inout] aIterator A pointer to the Network Data iterator context.
* @param[in] aRloc16 The RLOC16 value.
* @param[out] aConfig A pointer to where the On Mesh Prefix information will be placed.
*
* @retval kThreadError_None Successfully found the next On Mesh prefix.
* @retval kThreadError_NotFound No subsequent On Mesh prefix exists in the Thread Network Data.
*
*/
ThreadError GetNextOnMeshPrefix(otNetworkDataIterator *aIterator, uint16_t aRloc16, otBorderRouterConfig *aConfig);
/**
* This method provides the next external route in the Thread Network Data.
*
* @param[inout] aIterator A pointer to the Network Data iterator context.
* @param[out] aConfig A pointer to where the external route information will be placed.
*
* @retval kThreadError_None Successfully found the next external route.
* @retval kThreadError_NotFound No subsequent external route exists in the Thread Network Data.
*
*/
ThreadError GetNextExternalRoute(otNetworkDataIterator *aIterator, otExternalRouteConfig *aConfig);
/**
* This method provides the next external route in the Thread Network Data for a given RLOC16.
*
* @param[inout] aIterator A pointer to the Network Data iterator context.
* @param[in] aRloc16 The RLOC16 value.
* @param[out] aConfig A pointer to where the external route information will be placed.
*
* @retval kThreadError_None Successfully found the next external route.
* @retval kThreadError_NotFound No subsequent external route exists in the Thread Network Data.
*
*/
ThreadError GetNextExternalRoute(otNetworkDataIterator *aIterator, uint16_t aRloc16,
otExternalRouteConfig *aConfig);
/**
* This method indicates whether or not the Thread Network Data contains all of the on mesh prefix information
* in @p aCompare associated with @p aRloc16.
*
* @param[in] aCompare The Network Data to use for the query.
* @param[in] aRloc16 The RLOC16 to consider.
*
* @returns TRUE if this object contains all on mesh prefix information in @p aCompare associated with @p aRloc16,
* FALSE otherwise.
*
*/
bool ContainsOnMeshPrefixes(NetworkData &aCompare, uint16_t aRloc16);
/**
* This method indicates whether or not the Thread Network Data contains all of the external route information
* in @p aCompare associated with @p aRloc16.
*
* @param[in] aCompare The Network Data to use for the query.
* @param[in] aRloc16 The RLOC16 to consider.
*
* @returns TRUE if this object contains all external route information in @p aCompare associated with @p aRloc16,
* FALSE otherwise.
*
*/
bool ContainsExternalRoutes(NetworkData &aCompare, uint16_t aRloc16);
protected:
/**
* This method returns a pointer to the Border Router TLV within a given Prefix TLV.
+22 -1
View File
@@ -43,7 +43,8 @@ namespace NetworkData {
Local::Local(ThreadNetif &aThreadNetif):
NetworkData(aThreadNetif),
mOldRloc(Mac::kShortAddrInvalid)
mOldRloc(Mac::kShortAddrInvalid),
mLeader(aThreadNetif.GetNetworkDataLeader())
{
}
@@ -195,13 +196,33 @@ ThreadError Local::UpdateRloc(BorderRouterTlv &aBorderRouter)
return kThreadError_None;
}
bool Local::IsOnMeshPrefixConsistent(void)
{
return (mLeader.ContainsOnMeshPrefixes(*this, mMle.GetRloc16()) &&
ContainsOnMeshPrefixes(mLeader, mMle.GetRloc16()));
}
bool Local::IsExternalRouteConsistent(void)
{
return (mLeader.ContainsExternalRoutes(*this, mMle.GetRloc16()) &&
ContainsExternalRoutes(mLeader, mMle.GetRloc16()));
}
ThreadError Local::SendServerDataNotification(void)
{
ThreadError error = kThreadError_None;
uint16_t rloc = mMle.GetRloc16();
VerifyOrExit((mMle.GetDeviceMode() & Mle::ModeTlv::kModeFFD) == 0 ||
(mMle.IsRouterRoleEnabled() == false) ||
(mMle.GetDeviceState() >= Mle::kDeviceStateRouter) ||
(mMle.GetActiveRouterCount() >= mMle.GetRouterUpgradeThreshold()),
error = kThreadError_InvalidState);
UpdateRloc();
VerifyOrExit(!IsOnMeshPrefixConsistent() || !IsExternalRouteConsistent(), error = kThreadError_None);
if (mOldRloc == rloc)
{
mOldRloc = Mac::kShortAddrInvalid;
+5
View File
@@ -135,7 +135,12 @@ private:
ThreadError UpdateRloc(HasRouteTlv &aHasRoute);
ThreadError UpdateRloc(BorderRouterTlv &aBorderRouter);
bool IsOnMeshPrefixConsistent(void);
bool IsExternalRouteConsistent(void);
uint16_t mOldRloc;
Leader &mLeader;
};
} // namespace NetworkData