mirror of
https://github.com/espressif/openthread.git
synced 2026-08-10 20:57:47 +00:00
Automatically update leader with network data. (#480)
This commit is contained in:
@@ -961,6 +961,8 @@ void Mle::HandleNetifStateChanged(uint32_t aFlags)
|
||||
{
|
||||
mSendChildUpdateRequest.Post();
|
||||
}
|
||||
|
||||
mNetif.GetNetworkDataLocal().SendServerDataNotification();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1369,6 +1369,8 @@ ThreadError MleRouter::HandleAdvertisement(const Message &aMessage, const Ip6::M
|
||||
|
||||
UpdateRoutes(route, routerId);
|
||||
|
||||
mNetif.GetNetworkDataLocal().SendServerDataNotification();
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user