diff --git a/src/core/thread/mle.cpp b/src/core/thread/mle.cpp index e3699a2a6..e5de65500 100644 --- a/src/core/thread/mle.cpp +++ b/src/core/thread/mle.cpp @@ -1977,8 +1977,7 @@ ThreadError Mle::HandleParentResponse(const Message &aMessage, const Ip6::Messag switch (mParentRequestMode) { case kMleAttachAnyPartition: - VerifyOrExit((mDeviceMode & ModeTlv::kModeFFD) == 0 || - leaderData.GetPartitionId() != mLeaderData.GetPartitionId() || + VerifyOrExit(leaderData.GetPartitionId() != mLeaderData.GetPartitionId() || static_cast(connectivity.GetIdSequence() - mMleRouter.GetRouterIdSequence()) > 0,); break; diff --git a/src/core/thread/mle_router.cpp b/src/core/thread/mle_router.cpp index 9ce41d2a6..d0e6cd753 100644 --- a/src/core/thread/mle_router.cpp +++ b/src/core/thread/mle_router.cpp @@ -1121,33 +1121,26 @@ exit: ThreadError MleRouter::ProcessRouteTlv(const RouteTlv &aRoute) { ThreadError error = kThreadError_None; - int8_t diff = static_cast(aRoute.GetRouterIdSequence() - mRouterIdSequence); - bool old; - // check for newer route data - if (diff > 0 || mDeviceState == kDeviceStateDetached || mDeviceState == kDeviceStateChild) + mRouterIdSequence = aRoute.GetRouterIdSequence(); + mRouterIdSequenceLastUpdated = Timer::GetNow(); + + for (uint8_t i = 0; i <= kMaxRouterId; i++) { - mRouterIdSequence = aRoute.GetRouterIdSequence(); - mRouterIdSequenceLastUpdated = Timer::GetNow(); + bool old = mRouters[i].mAllocated; + mRouters[i].mAllocated = aRoute.IsRouterIdSet(i); - for (uint8_t i = 0; i <= kMaxRouterId; i++) + if (old && !mRouters[i].mAllocated) { - old = mRouters[i].mAllocated; - mRouters[i].mAllocated = aRoute.IsRouterIdSet(i); - - if (old && !mRouters[i].mAllocated) - { - mRouters[i].mNextHop = kInvalidRouterId; - mAddressResolver.Remove(i); - } - } - - if (GetDeviceState() == kDeviceStateRouter && !mRouters[mRouterId].mAllocated) - { - BecomeDetached(); - ExitNow(error = kThreadError_NoRoute); + mRouters[i].mNextHop = kInvalidRouterId; + mAddressResolver.Remove(i); } + } + if (GetDeviceState() == kDeviceStateRouter && !mRouters[mRouterId].mAllocated) + { + BecomeDetached(); + ExitNow(error = kThreadError_NoRoute); } exit: @@ -1317,13 +1310,42 @@ ThreadError MleRouter::HandleAdvertisement(const Message &aMessage, const Ip6::M ExitNow(); } - VerifyOrExit(IsActiveRouter(sourceAddress.GetRloc16()), ;); - if (mDeviceMode & ModeTlv::kModeFFD) { - SuccessOrExit(error = ProcessRouteTlv(route)); + bool processRouteTlv = false; + + switch (mDeviceState) + { + case kDeviceStateDisabled: + case kDeviceStateDetached: + break; + + case kDeviceStateChild: + if (sourceAddress.GetRloc16() == mParent.mValid.mRloc16) + { + processRouteTlv = true; + } + + break; + + case kDeviceStateRouter: + case kDeviceStateLeader: + if (static_cast(route.GetRouterIdSequence() - mRouterIdSequence) > 0) + { + processRouteTlv = true; + } + + break; + } + + if (processRouteTlv) + { + SuccessOrExit(error = ProcessRouteTlv(route)); + } } + VerifyOrExit(IsActiveRouter(sourceAddress.GetRloc16()), ;); + routerId = GetRouterId(sourceAddress.GetRloc16()); VerifyOrExit(IsRouterIdValid(routerId), error = kThreadError_Parse); diff --git a/tests/scripts/thread-cert/Cert_5_5_04_SplitMergeRouters.py b/tests/scripts/thread-cert/Cert_5_5_04_SplitMergeRouters.py index 4701b73bb..86ca5c4a6 100755 --- a/tests/scripts/thread-cert/Cert_5_5_04_SplitMergeRouters.py +++ b/tests/scripts/thread-cert/Cert_5_5_04_SplitMergeRouters.py @@ -32,37 +32,35 @@ import unittest import node -LEADER1 = 1 +LEADER = 1 ROUTER1 = 2 ROUTER2 = 3 ROUTER3 = 4 ROUTER4 = 5 -ED1 = 6 class Cert_5_5_4_SplitMergeRouters(unittest.TestCase): def setUp(self): self.nodes = {} - for i in range(1,7): + for i in range(1,6): self.nodes[i] = node.Node(i) - self.nodes[LEADER1].set_panid(0xface) - self.nodes[LEADER1].set_mode('rsdn') - self.nodes[LEADER1].add_whitelist(self.nodes[ROUTER1].get_addr64()) - self.nodes[LEADER1].add_whitelist(self.nodes[ROUTER2].get_addr64()) - self.nodes[LEADER1].add_whitelist(self.nodes[ED1].get_addr64()) - self.nodes[LEADER1].enable_whitelist() - self.nodes[LEADER1].set_router_selection_jitter(1) + self.nodes[LEADER].set_panid(0xface) + self.nodes[LEADER].set_mode('rsdn') + self.nodes[LEADER].add_whitelist(self.nodes[ROUTER1].get_addr64()) + self.nodes[LEADER].add_whitelist(self.nodes[ROUTER2].get_addr64()) + self.nodes[LEADER].enable_whitelist() + self.nodes[LEADER].set_router_selection_jitter(1) self.nodes[ROUTER1].set_panid(0xface) self.nodes[ROUTER1].set_mode('rsdn') - self.nodes[ROUTER1].add_whitelist(self.nodes[LEADER1].get_addr64()) + self.nodes[ROUTER1].add_whitelist(self.nodes[LEADER].get_addr64()) self.nodes[ROUTER1].add_whitelist(self.nodes[ROUTER3].get_addr64()) self.nodes[ROUTER1].enable_whitelist() self.nodes[ROUTER1].set_router_selection_jitter(1) self.nodes[ROUTER2].set_panid(0xface) self.nodes[ROUTER2].set_mode('rsdn') - self.nodes[ROUTER2].add_whitelist(self.nodes[LEADER1].get_addr64()) + self.nodes[ROUTER2].add_whitelist(self.nodes[LEADER].get_addr64()) self.nodes[ROUTER2].add_whitelist(self.nodes[ROUTER4].get_addr64()) self.nodes[ROUTER2].enable_whitelist() self.nodes[ROUTER2].set_router_selection_jitter(1) @@ -71,7 +69,6 @@ class Cert_5_5_4_SplitMergeRouters(unittest.TestCase): self.nodes[ROUTER3].set_mode('rsdn') self.nodes[ROUTER3].add_whitelist(self.nodes[ROUTER1].get_addr64()) self.nodes[ROUTER3].enable_whitelist() - self.nodes[ROUTER3].set_network_id_timeout(110) self.nodes[ROUTER3].set_router_selection_jitter(1) self.nodes[ROUTER4].set_panid(0xface) @@ -80,20 +77,15 @@ class Cert_5_5_4_SplitMergeRouters(unittest.TestCase): self.nodes[ROUTER4].enable_whitelist() self.nodes[ROUTER4].set_router_selection_jitter(1) - self.nodes[ED1].set_panid(0xface) - self.nodes[ED1].set_mode('rsn') - self.nodes[ED1].add_whitelist(self.nodes[LEADER1].get_addr64()) - self.nodes[ED1].enable_whitelist() - def tearDown(self): for node in list(self.nodes.values()): node.stop() del self.nodes def test(self): - self.nodes[LEADER1].start() - self.nodes[LEADER1].set_state('leader') - self.assertEqual(self.nodes[LEADER1].get_state(), 'leader') + self.nodes[LEADER].start() + self.nodes[LEADER].set_state('leader') + self.assertEqual(self.nodes[LEADER].get_state(), 'leader') self.nodes[ROUTER1].start() time.sleep(5) @@ -111,29 +103,18 @@ class Cert_5_5_4_SplitMergeRouters(unittest.TestCase): time.sleep(5) self.assertEqual(self.nodes[ROUTER4].get_state(), 'router') - self.nodes[ED1].start() - time.sleep(5) - self.assertEqual(self.nodes[ED1].get_state(), 'child') + self.nodes[LEADER].stop() + time.sleep(150) - self.nodes[LEADER1].stop() + self.nodes[LEADER].start() + time.sleep(50) - self.nodes[ED1].add_whitelist(self.nodes[ROUTER1].get_addr64()) - self.nodes[ROUTER1].add_whitelist(self.nodes[ED1].get_addr64()) + self.assertEqual(self.nodes[LEADER].get_state(), 'router') - time.sleep(130) - #self.assertEqual(self.nodes[ROUTER3].get_state(), 'leader') - #self.assertEqual(self.nodes[ROUTER1].get_state(), 'router') - - self.nodes[LEADER1].start() - time.sleep(5) - self.assertEqual(self.nodes[LEADER1].get_state(), 'router') - - time.sleep(60) - - addrs = self.nodes[ED1].get_addrs() + addrs = self.nodes[ROUTER4].get_addrs() for addr in addrs: if addr[0:4] != 'fe80': - self.assertTrue(self.nodes[ROUTER2].ping(addr)) + self.assertTrue(self.nodes[ROUTER3].ping(addr)) if __name__ == '__main__': unittest.main() diff --git a/tests/scripts/thread-cert/Cert_5_5_05_SplitMergeREED.py b/tests/scripts/thread-cert/Cert_5_5_05_SplitMergeREED.py index ea7417a30..2f6acbe64 100755 --- a/tests/scripts/thread-cert/Cert_5_5_05_SplitMergeREED.py +++ b/tests/scripts/thread-cert/Cert_5_5_05_SplitMergeREED.py @@ -32,51 +32,45 @@ import unittest import node -LEADER1 = 1 +LEADER = 1 ROUTER1 = 2 ROUTER2 = 3 ROUTER3 = 4 -REED2 = 5 +ROUTER15 = 16 +REED1 = 17 class Cert_5_5_5_SplitMergeREED(unittest.TestCase): def setUp(self): self.nodes = {} - for i in range(1,6): + for i in range(1,18): self.nodes[i] = node.Node(i) - self.nodes[LEADER1].set_panid(0xface) - self.nodes[LEADER1].set_mode('rsdn') - self.nodes[LEADER1].add_whitelist(self.nodes[ROUTER2].get_addr64()) - self.nodes[LEADER1].add_whitelist(self.nodes[ROUTER3].get_addr64()) - self.nodes[LEADER1].enable_whitelist() + self.nodes[LEADER].set_panid(0xface) + self.nodes[LEADER].set_mode('rsdn') + for i in range(ROUTER2, ROUTER15+1): + self.nodes[LEADER].add_whitelist(self.nodes[i].get_addr64()) + self.nodes[LEADER].enable_whitelist() + + for i in range(ROUTER2, ROUTER15+1): + self.nodes[i].set_panid(0xface) + self.nodes[i].set_mode('rsdn') + self.nodes[i].add_whitelist(self.nodes[LEADER].get_addr64()) + self.nodes[i].enable_whitelist() + self.nodes[i].set_router_selection_jitter(1) self.nodes[ROUTER1].set_panid(0xface) self.nodes[ROUTER1].set_mode('rsdn') self.nodes[ROUTER1].add_whitelist(self.nodes[ROUTER3].get_addr64()) - self.nodes[ROUTER1].add_whitelist(self.nodes[REED2].get_addr64()) self.nodes[ROUTER1].enable_whitelist() self.nodes[ROUTER1].set_router_selection_jitter(1) - self.nodes[ROUTER2].set_panid(0xface) - self.nodes[ROUTER2].set_mode('rsdn') - self.nodes[ROUTER2].add_whitelist(self.nodes[LEADER1].get_addr64()) - self.nodes[ROUTER2].add_whitelist(self.nodes[REED2].get_addr64()) - self.nodes[ROUTER2].enable_whitelist() - self.nodes[ROUTER2].set_router_selection_jitter(1) - - self.nodes[ROUTER3].set_panid(0xface) - self.nodes[ROUTER3].set_mode('rsdn') - self.nodes[ROUTER3].add_whitelist(self.nodes[LEADER1].get_addr64()) + self.nodes[ROUTER2].add_whitelist(self.nodes[REED1].get_addr64()) self.nodes[ROUTER3].add_whitelist(self.nodes[ROUTER1].get_addr64()) - self.nodes[ROUTER3].enable_whitelist() - self.nodes[ROUTER3].set_router_selection_jitter(1) - self.nodes[REED2].set_panid(0xface) - self.nodes[REED2].set_mode('rsdn') - self.nodes[REED2].add_whitelist(self.nodes[ROUTER1].get_addr64()) - self.nodes[REED2].add_whitelist(self.nodes[ROUTER2].get_addr64()) - self.nodes[REED2].enable_whitelist() - self.nodes[REED2].set_router_upgrade_threshold(0) + self.nodes[REED1].set_panid(0xface) + self.nodes[REED1].set_mode('rsdn') + self.nodes[REED1].add_whitelist(self.nodes[ROUTER2].get_addr64()) + self.nodes[REED1].enable_whitelist() def tearDown(self): for node in list(self.nodes.values()): @@ -84,33 +78,33 @@ class Cert_5_5_5_SplitMergeREED(unittest.TestCase): del self.nodes def test(self): - self.nodes[LEADER1].start() - self.nodes[LEADER1].set_state('leader') - self.assertEqual(self.nodes[LEADER1].get_state(), 'leader') + self.nodes[LEADER].start() + self.nodes[LEADER].set_state('leader') + self.assertEqual(self.nodes[LEADER].get_state(), 'leader') - self.nodes[ROUTER2].start() - time.sleep(5) - self.assertEqual(self.nodes[ROUTER2].get_state(), 'router') - - self.nodes[REED2].start() - time.sleep(5) - self.assertEqual(self.nodes[REED2].get_state(), 'child') - - self.nodes[ROUTER3].start() - time.sleep(5) - self.assertEqual(self.nodes[ROUTER3].get_state(), 'router') + for i in range(ROUTER2, ROUTER15+1): + self.nodes[i].start() + time.sleep(5) + self.assertEqual(self.nodes[i].get_state(), 'router') self.nodes[ROUTER1].start() time.sleep(5) self.assertEqual(self.nodes[ROUTER1].get_state(), 'router') + self.nodes[REED1].start() + time.sleep(5) + self.assertEqual(self.nodes[REED1].get_state(), 'child') + + self.nodes[ROUTER1].add_whitelist(self.nodes[REED1].get_addr64()) + self.nodes[REED1].add_whitelist(self.nodes[ROUTER1].get_addr64()) + self.nodes[ROUTER3].stop() - time.sleep(150) + time.sleep(140) - self.assertEqual(self.nodes[REED2].get_state(), 'router') - self.assertEqual(self.nodes[ROUTER1].get_state(), 'router') + self.assertEqual(self.nodes[ROUTER1].get_state(), 'child') + self.assertEqual(self.nodes[REED1].get_state(), 'router') - addrs = self.nodes[LEADER1].get_addrs() + addrs = self.nodes[LEADER].get_addrs() for addr in addrs: if addr[0:4] != 'fe80': self.assertTrue(self.nodes[ROUTER1].ping(addr))