From 5902ce9222bd563bcaa5ab00c445b096ba47642f Mon Sep 17 00:00:00 2001 From: Jonathan Hui Date: Thu, 2 Apr 2020 09:41:16 -0700 Subject: [PATCH] [network-data] periodically check for stale child ids (#4779) A parent is responsible for removing stale child entries from the network data. The existing implementation only triggered a SVR_DATA.ntf message when new network data is received. In some cases, the SVR_DATA.ntf message may not be sent due to rate limiting or lack of message buffers. This commit turns this process into a periodic check to ensure that stale child entires are removed even if a failure in sending the SVR_DATA.ntf occurs. --- src/core/thread/mle_router.cpp | 20 ++------------------ src/core/thread/network_data_leader_ftd.cpp | 17 +++++++++++++++++ src/core/thread/network_data_leader_ftd.hpp | 6 ++++++ 3 files changed, 25 insertions(+), 18 deletions(-) diff --git a/src/core/thread/mle_router.cpp b/src/core/thread/mle_router.cpp index 0504e7598..0c414fed7 100644 --- a/src/core/thread/mle_router.cpp +++ b/src/core/thread/mle_router.cpp @@ -2714,24 +2714,6 @@ void MleRouter::HandleNetworkDataUpdateRouter(void) SynchronizeChildNetworkData(); - // Detect if any server entry with invalid child RLOC16 - { - NetworkData::Iterator iterator = NetworkData::kIteratorInit; - uint16_t rloc16 = Mac::kShortAddrInvalid; - - while (Get().GetNextServer(iterator, rloc16) == OT_ERROR_NONE) - { - if (!IsActiveRouter(rloc16) && RouterIdMatch(GetRloc16(), rloc16) && - mChildTable.FindChild(rloc16, Child::kInStateValid) == NULL) - { - Get().SendServerDataNotification(rloc16); - // In Thread 1.1 Specification 5.15.6.1, only one RLOC16 TLV entry may appear in SRV_DATA.ntf. - // So break here. - break; - } - } - } - exit: return; } @@ -2740,6 +2722,8 @@ void MleRouter::SynchronizeChildNetworkData(void) { VerifyOrExit(mRole == OT_DEVICE_ROLE_ROUTER || mRole == OT_DEVICE_ROLE_LEADER); + Get().RemoveStaleChildEntries(); + for (ChildTable::Iterator iter(GetInstance(), Child::kInStateValid); !iter.IsDone(); iter++) { Child & child = *iter.GetChild(); diff --git a/src/core/thread/network_data_leader_ftd.cpp b/src/core/thread/network_data_leader_ftd.cpp index 6b2cb6c1c..623e5cf0d 100644 --- a/src/core/thread/network_data_leader_ftd.cpp +++ b/src/core/thread/network_data_leader_ftd.cpp @@ -1504,6 +1504,23 @@ void Leader::HandleTimer(void) } } +void Leader::RemoveStaleChildEntries(void) +{ + Iterator iterator = kIteratorInit; + uint16_t rloc16; + + while (GetNextServer(iterator, rloc16) == OT_ERROR_NONE) + { + if (!Mle::Mle::IsActiveRouter(rloc16) && Mle::Mle::RouterIdMatch(Get().GetRloc16(), rloc16) && + Get().FindChild(rloc16, Child::kInStateValid) == NULL) + { + // In Thread 1.1 Specification 5.15.6.1, only one RLOC16 TLV entry may appear in SRV_DATA.ntf. + SendServerDataNotification(rloc16); + break; + } + } +} + } // namespace NetworkData } // namespace ot diff --git a/src/core/thread/network_data_leader_ftd.hpp b/src/core/thread/network_data_leader_ftd.hpp index f0db3879b..0d680bf93 100644 --- a/src/core/thread/network_data_leader_ftd.hpp +++ b/src/core/thread/network_data_leader_ftd.hpp @@ -168,6 +168,12 @@ public: */ ServiceTlv *FindServiceById(uint8_t aServiceId); + /** + * This method sends SVR_DATA.ntf message for any stale child entries that exist in the network data. + * + */ + void RemoveStaleChildEntries(void); + private: static void HandleServerData(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo); void HandleServerData(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);