Skip to content

Commit

Permalink
[mle] fix partition merging with REEDs (openthread#2476)
Browse files Browse the repository at this point in the history
REEDs periodically transmit MLE Advertisement messages to support merging
partitions.  However, REEDs do not include Route64 TLVs in their MLE
Advertisement messages.

This commit removes the strict requirement check when handling MLE
Advertisement messages, allowing such messages sent by REEDs to trigger
the partition merging process.
  • Loading branch information
jwhui authored Jan 15, 2018
1 parent 15885dc commit 3306509
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 16 deletions.
54 changes: 38 additions & 16 deletions src/core/thread/mle_router.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1308,6 +1308,30 @@ uint8_t MleRouter::GetActiveNeighborRouterCount(void) const
return rval;
}

bool MleRouter::IsSingleton(const RouteTlv &aRouteTlv)
{
bool rval = true;
uint8_t count = 0;

// REEDs do not include a Route TLV and indicate not a singleton
if (!aRouteTlv.IsValid())
{
ExitNow(rval = false);
}

// Check if 2 or more active routers
for (uint8_t i = 0; i <= kMaxRouterId; i++)
{
if (aRouteTlv.IsRouterIdSet(i) && (++count >= 2))
{
ExitNow(rval = false);
}
}

exit:
return rval;
}

otError MleRouter::HandleAdvertisement(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
{
ThreadNetif &netif = GetNetif();
Expand Down Expand Up @@ -1341,9 +1365,16 @@ otError MleRouter::HandleAdvertisement(const Message &aMessage, const Ip6::Messa
SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kLeaderData, sizeof(leaderData), leaderData));
VerifyOrExit(leaderData.IsValid(), error = OT_ERROR_PARSE);

// Route Data
SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kRoute, sizeof(route), route));
VerifyOrExit(route.IsValid(), error = OT_ERROR_PARSE);
// Route Data (optional)
if (Tlv::GetTlv(aMessage, Tlv::kRoute, sizeof(route), route) == OT_ERROR_NONE)
{
VerifyOrExit(route.IsValid(), error = OT_ERROR_PARSE);
}
else
{
// mark that a Route TLV was not included
route.SetLength(0);
}

partitionId = leaderData.GetPartitionId();

Expand All @@ -1354,7 +1385,8 @@ otError MleRouter::HandleAdvertisement(const Message &aMessage, const Ip6::Messa

VerifyOrExit(linkMargin >= OPENTHREAD_CONFIG_MLE_PARTITION_MERGE_MARGIN_MIN, error = OT_ERROR_LINK_MARGIN_LOW);

if ((mDeviceMode & ModeTlv::kModeFFD) &&
if (route.IsValid() &&
(mDeviceMode & ModeTlv::kModeFFD) &&
(mLastPartitionIdTimeout > 0) &&
(partitionId == mLastPartitionId))
{
Expand All @@ -1368,17 +1400,7 @@ otError MleRouter::HandleAdvertisement(const Message &aMessage, const Ip6::Messa
ExitNow();
}

routerCount = 0;

for (uint8_t i = 0; i <= kMaxRouterId; i++)
{
if (route.IsRouterIdSet(i))
{
routerCount++;
}
}

if (ComparePartitions(routerCount <= 1, leaderData, IsSingleton(), mLeaderData) > 0)
if (ComparePartitions(IsSingleton(route), leaderData, IsSingleton(), mLeaderData) > 0)
{
BecomeChild(kAttachBetter);
}
Expand All @@ -1397,7 +1419,7 @@ otError MleRouter::HandleAdvertisement(const Message &aMessage, const Ip6::Messa
ExitNow();
}

VerifyOrExit(IsActiveRouter(sourceAddress.GetRloc16()));
VerifyOrExit(IsActiveRouter(sourceAddress.GetRloc16()) && route.IsValid());
routerId = GetRouterId(sourceAddress.GetRloc16());
router = GetRouter(routerId);
VerifyOrExit(router != NULL, error = OT_ERROR_PARSE);
Expand Down
2 changes: 2 additions & 0 deletions src/core/thread/mle_router_ftd.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -813,6 +813,8 @@ class MleRouter: public Mle

static uint8_t LinkQualityToCost(uint8_t aLinkQuality);

static bool IsSingleton(const RouteTlv &aRouteTlv);

Child *NewChild(void);
Child *FindChild(uint16_t aChildId);
Child *FindChild(const Mac::ExtAddress &aMacAddr);
Expand Down

0 comments on commit 3306509

Please sign in to comment.