diff --git a/src/core/api/thread_ftd_api.cpp b/src/core/api/thread_ftd_api.cpp index e478092b0..d79579325 100644 --- a/src/core/api/thread_ftd_api.cpp +++ b/src/core/api/thread_ftd_api.cpp @@ -380,7 +380,7 @@ void otThreadRegisterNeighborTableCallback(otInstance *aInstance, otNeighborTabl { Instance &instance = *static_cast(aInstance); - instance.Get().RegisterNeighborTableChangedCallback(aCallback); + instance.Get().RegisterCallback(aCallback); } void otThreadSetDiscoveryRequestCallback(otInstance * aInstance, diff --git a/src/core/thread/mle_router.cpp b/src/core/thread/mle_router.cpp index 76a52e988..822614270 100644 --- a/src/core/thread/mle_router.cpp +++ b/src/core/thread/mle_router.cpp @@ -64,7 +64,6 @@ MleRouter::MleRouter(Instance &aInstance) , mAddressRelease(OT_URI_PATH_ADDRESS_RELEASE, &MleRouter::HandleAddressRelease, this) , mChildTable(aInstance) , mRouterTable(aInstance) - , mNeighborTableChangedCallback(nullptr) , mChallengeTimeout(0) , mNextChildId(kMaxChildId) , mNetworkIdTimeout(kNetworkIdTimeout) @@ -1004,7 +1003,7 @@ otError MleRouter::HandleLinkAccept(const Message & aMessage, router->SetState(Neighbor::kStateValid); router->SetKeySequence(aKeySequence); - Signal(OT_NEIGHBOR_TABLE_EVENT_ROUTER_ADDED, *router); + mNeighborTable.Signal(OT_NEIGHBOR_TABLE_EVENT_ROUTER_ADDED, *router); if (aRequest) { @@ -3413,7 +3412,7 @@ void MleRouter::RemoveNeighbor(Neighbor &aNeighbor) if (aNeighbor.IsStateValidOrRestoring()) { - Signal(OT_NEIGHBOR_TABLE_EVENT_CHILD_REMOVED, aNeighbor); + mNeighborTable.Signal(OT_NEIGHBOR_TABLE_EVENT_CHILD_REMOVED, aNeighbor); } Get().ClearAllMessagesForSleepyChild(static_cast(aNeighbor)); @@ -3430,7 +3429,7 @@ void MleRouter::RemoveNeighbor(Neighbor &aNeighbor) { OT_ASSERT(mRouterTable.Contains(aNeighbor)); - Signal(OT_NEIGHBOR_TABLE_EVENT_ROUTER_REMOVED, aNeighbor); + mNeighborTable.Signal(OT_NEIGHBOR_TABLE_EVENT_ROUTER_REMOVED, aNeighbor); mRouterTable.RemoveRouterLink(static_cast(aNeighbor)); } @@ -4369,7 +4368,7 @@ void MleRouter::SetChildStateToValid(Child &aChild) Get().UpdateProxiedSubscriptions(aChild, nullptr, 0); #endif - Signal(OT_NEIGHBOR_TABLE_EVENT_CHILD_ADDED, aChild); + mNeighborTable.Signal(OT_NEIGHBOR_TABLE_EVENT_CHILD_ADDED, aChild); exit: return; @@ -4441,55 +4440,6 @@ exit: return error; } -void MleRouter::Signal(otNeighborTableEvent aEvent, Neighbor &aNeighbor) -{ - if (mNeighborTableChangedCallback != nullptr) - { - otNeighborTableEntryInfo info; - otError error; - - OT_UNUSED_VARIABLE(error); - - info.mInstance = &GetInstance(); - - switch (aEvent) - { - case OT_NEIGHBOR_TABLE_EVENT_CHILD_ADDED: - case OT_NEIGHBOR_TABLE_EVENT_CHILD_REMOVED: - static_cast(info.mInfo.mChild).SetFrom(static_cast(aNeighbor)); - break; - - case OT_NEIGHBOR_TABLE_EVENT_ROUTER_ADDED: - case OT_NEIGHBOR_TABLE_EVENT_ROUTER_REMOVED: - static_cast(info.mInfo.mRouter).SetFrom(aNeighbor); - break; - } - - mNeighborTableChangedCallback(aEvent, &info); - } - -#if OPENTHREAD_CONFIG_OTNS_ENABLE - Get().EmitNeighborChange(aEvent, aNeighbor); -#endif - - switch (aEvent) - { - case OT_NEIGHBOR_TABLE_EVENT_CHILD_ADDED: - Get().Signal(kEventThreadChildAdded); - break; - - case OT_NEIGHBOR_TABLE_EVENT_CHILD_REMOVED: - Get().Signal(kEventThreadChildRemoved); -#if OPENTHREAD_CONFIG_TMF_PROXY_DUA_ENABLE - Get().UpdateChildDomainUnicastAddress(static_cast(aNeighbor), ChildDuaState::kRemoved); -#endif - break; - - default: - break; - } -} - #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE void MleRouter::HandleTimeSync(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo, const Neighbor *aNeighbor) { diff --git a/src/core/thread/mle_router.hpp b/src/core/thread/mle_router.hpp index 4518617bd..73040f2f7 100644 --- a/src/core/thread/mle_router.hpp +++ b/src/core/thread/mle_router.hpp @@ -476,20 +476,6 @@ public: */ otError GetMaxChildTimeout(uint32_t &aTimeout) const; - /** - * This method register the "neighbor table changed" callback function. - * - * The provided callback (if non-nullptr) will be invoked when a child/router entry is being added/remove to/from - * the neighbor table. Subsequent calls to this method will overwrite the previous callback. - * - * @param[in] aCallback A pointer to callback handler function. - * - */ - void RegisterNeighborTableChangedCallback(otNeighborTableCallback aCallback) - { - mNeighborTableChangedCallback = aCallback; - } - /** * This function sets the callback that is called when processing an MLE Discovery Request message. * @@ -503,15 +489,6 @@ public: mDiscoveryRequestCallbackContext = aContext; } - /** - * This method signals a "neighbor table changed" events (invoking the registered callback function). - * - * @param[in] aEvent The event to emit (child/router added/removed). - * @param[in] aNeighbor The neighbor that is being added/removed. - * - */ - void Signal(otNeighborTableEvent aEvent, Neighbor &aNeighbor); - /** * This method resets the MLE Advertisement Trickle timer interval. * @@ -682,8 +659,6 @@ private: ChildTable mChildTable; RouterTable mRouterTable; - otNeighborTableCallback mNeighborTableChangedCallback; - uint8_t mChallengeTimeout; Challenge mChallenge; diff --git a/src/core/thread/neighbor_table.cpp b/src/core/thread/neighbor_table.cpp index a5184a4e3..9583d9b1f 100644 --- a/src/core/thread/neighbor_table.cpp +++ b/src/core/thread/neighbor_table.cpp @@ -36,11 +36,13 @@ #include "common/code_utils.hpp" #include "common/instance.hpp" #include "common/locator-getters.hpp" +#include "thread/dua_manager.hpp" namespace ot { NeighborTable::NeighborTable(Instance &aInstance) : InstanceLocator(aInstance) + , mCallback(nullptr) { } @@ -253,4 +255,51 @@ exit: #endif +void NeighborTable::Signal(Event aEvent, const Neighbor &aNeighbor) +{ + if (mCallback != nullptr) + { + EntryInfo info; + + info.mInstance = &GetInstance(); + + switch (aEvent) + { + case OT_NEIGHBOR_TABLE_EVENT_CHILD_ADDED: + case OT_NEIGHBOR_TABLE_EVENT_CHILD_REMOVED: + static_cast(info.mInfo.mChild).SetFrom(static_cast(aNeighbor)); + break; + + case OT_NEIGHBOR_TABLE_EVENT_ROUTER_ADDED: + case OT_NEIGHBOR_TABLE_EVENT_ROUTER_REMOVED: + static_cast(info.mInfo.mRouter).SetFrom(aNeighbor); + break; + } + + mCallback(aEvent, &info); + } + +#if OPENTHREAD_CONFIG_OTNS_ENABLE + Get().EmitNeighborChange(aEvent, aNeighbor); +#endif + + switch (aEvent) + { + case OT_NEIGHBOR_TABLE_EVENT_CHILD_ADDED: + Get().Signal(kEventThreadChildAdded); + break; + + case OT_NEIGHBOR_TABLE_EVENT_CHILD_REMOVED: + Get().Signal(kEventThreadChildRemoved); +#if OPENTHREAD_CONFIG_TMF_PROXY_DUA_ENABLE + Get().UpdateChildDomainUnicastAddress(static_cast(aNeighbor), + Mle::ChildDuaState::kRemoved); +#endif + break; + + default: + break; + } +} + } // namespace ot diff --git a/src/core/thread/neighbor_table.hpp b/src/core/thread/neighbor_table.hpp index 24452a45c..459f46e02 100644 --- a/src/core/thread/neighbor_table.hpp +++ b/src/core/thread/neighbor_table.hpp @@ -48,6 +48,30 @@ namespace ot { class NeighborTable : public InstanceLocator { public: + /** + * This function pointer is called to notify that a child or router neighbor is being added to or removed from + * neighbor table. + * + * Note that this callback in invoked while the neighbor/child table is being updated and always before the related + * `Notifier` event. + * + */ + typedef otNeighborTableCallback Callback; + + /** + * This type represents a neighbor table entry info (child or router) and is used as a parameter in the neighbor + * table callback. + * + */ + typedef otNeighborTableEntryInfo EntryInfo; + + /** + * This enumeration defines the constants used in `NeighborTable::Callback` to indicate whether a child or router + * neighbor is being added or removed. + * + */ + typedef otNeighborTableEvent Event; + /** * This constructor initializes the `NeighborTable` instance. * @@ -158,12 +182,36 @@ public: */ otError GetNextNeighborInfo(otNeighborInfoIterator &aIterator, Neighbor::Info &aNeighInfo); + /** + * This method registers the "neighbor table changed" callback function. + * + * The provided callback (if non-nullptr) will be invoked when a child/router entry is being added/remove to/from + * the neighbor table. Subsequent calls to this method will overwrite the previous callback. + * + * @param[in] aCallback A pointer to callback handler function. + * + */ + void RegisterCallback(Callback aCallback) { mCallback = aCallback; } + + /** + * This method signals a "neighbor table changed" event. + * + * This method invokes the `NeighborTable::Callback` and also signals the change through a related `Notifier` event. + * + * @param[in] aEvent The event to emit (child/router added/removed). + * @param[in] aNeighbor The neighbor that is being added/removed. + * + */ + void Signal(Event aEvent, const Neighbor &aNeighbor); + private: Neighbor *FindParent(const Neighbor::AddressMatcher &aMatcher); Neighbor *FindNeighbor(const Neighbor::AddressMatcher &aMatcher); #if OPENTHREAD_FTD Neighbor *FindChildOrRouter(const Neighbor::AddressMatcher &aMatcher); #endif + + Callback mCallback; }; } // namespace ot diff --git a/src/core/thread/router_table.cpp b/src/core/thread/router_table.cpp index 478519b20..f1fc808e1 100644 --- a/src/core/thread/router_table.cpp +++ b/src/core/thread/router_table.cpp @@ -100,7 +100,7 @@ void RouterTable::ClearNeighbors(void) { if (router.IsStateValid()) { - Get().Signal(OT_NEIGHBOR_TABLE_EVENT_ROUTER_REMOVED, router); + Get().Signal(OT_NEIGHBOR_TABLE_EVENT_ROUTER_REMOVED, router); } router.SetState(Neighbor::kStateInvalid); diff --git a/src/core/utils/otns.cpp b/src/core/utils/otns.cpp index ea0fa52e1..f714e5a1d 100644 --- a/src/core/utils/otns.cpp +++ b/src/core/utils/otns.cpp @@ -107,7 +107,7 @@ void Otns::HandleNotifierEvents(Events aEvents) #endif } -void Otns::EmitNeighborChange(otNeighborTableEvent aEvent, Neighbor &aNeighbor) +void Otns::EmitNeighborChange(NeighborTable::Event aEvent, const Neighbor &aNeighbor) { switch (aEvent) { diff --git a/src/core/utils/otns.hpp b/src/core/utils/otns.hpp index 47069c4b7..c83ce7ddf 100644 --- a/src/core/utils/otns.hpp +++ b/src/core/utils/otns.hpp @@ -47,6 +47,7 @@ #include "common/notifier.hpp" #include "mac/mac_types.hpp" #include "net/ip6_address.hpp" +#include "thread/neighbor_table.hpp" #include "thread/topology.hpp" namespace ot { @@ -123,7 +124,7 @@ public: * @param[in] aNeighbor The neighbor that is added or removed. * */ - static void EmitNeighborChange(otNeighborTableEvent aEvent, Neighbor &aNeighbor); + static void EmitNeighborChange(NeighborTable::Event aEvent, const Neighbor &aNeighbor); /** * This function emits a transmit event to OTNS.