mirror of
https://github.com/espressif/openthread.git
synced 2026-08-09 20:27:47 +00:00
[child-supervision] change how child supervision gets started/stopped (#2627)
This commit removes the `Start()/Stop()` APIs from `ChildSupervisor` class. Instead `ChildSupervisor` class itself would decide when to start/stop. It registers a `Notifier` callback to be notified when the Thread role changes and/or when a child is added or removed. If MLE operation is enabled and there is at least one "valid" child in the child table, child supervision starts, otherwise it is stopped.
This commit is contained in:
committed by
Jonathan Hui
parent
11f326068c
commit
302c999367
@@ -80,7 +80,7 @@ public:
|
||||
*
|
||||
* @param[in] aCallback A reference to callback instance.
|
||||
* @param[in] aFlags A bit-field indicating specific state that has changed. See `OT_CHANGED_<STATE>`
|
||||
* definitions in `types.h`.
|
||||
* definitions in `instance.h`.
|
||||
*
|
||||
*/
|
||||
typedef void (*Handler)(Callback &aCallback, uint32_t aFlags);
|
||||
|
||||
@@ -140,7 +140,6 @@ otError ThreadNetif::Up(void)
|
||||
#if OPENTHREAD_ENABLE_CHANNEL_MONITOR
|
||||
GetInstance().GetChannelMonitor().Start();
|
||||
#endif
|
||||
mChildSupervisor.Start();
|
||||
mMleRouter.Enable();
|
||||
mIsUp = true;
|
||||
}
|
||||
@@ -157,7 +156,6 @@ otError ThreadNetif::Down(void)
|
||||
#if OPENTHREAD_ENABLE_CHANNEL_MONITOR
|
||||
GetInstance().GetChannelMonitor().Stop();
|
||||
#endif
|
||||
mChildSupervisor.Stop();
|
||||
mMleRouter.Disable();
|
||||
mMeshForwarder.Stop();
|
||||
GetIp6().RemoveNetif(*this);
|
||||
|
||||
@@ -53,28 +53,15 @@ ChildSupervisor::ChildSupervisor(Instance &aInstance)
|
||||
: InstanceLocator(aInstance)
|
||||
, mSupervisionInterval(kDefaultSupervisionInterval)
|
||||
, mTimer(aInstance, &ChildSupervisor::HandleTimer, this)
|
||||
, mNotifierCallback(&ChildSupervisor::HandleStateChanged, this)
|
||||
{
|
||||
}
|
||||
|
||||
void ChildSupervisor::Start(void)
|
||||
{
|
||||
VerifyOrExit(mSupervisionInterval != 0);
|
||||
VerifyOrExit(!mTimer.IsRunning());
|
||||
mTimer.Start(kOneSecond);
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void ChildSupervisor::Stop(void)
|
||||
{
|
||||
mTimer.Stop();
|
||||
aInstance.GetNotifier().RegisterCallback(mNotifierCallback);
|
||||
}
|
||||
|
||||
void ChildSupervisor::SetSupervisionInterval(uint16_t aInterval)
|
||||
{
|
||||
mSupervisionInterval = aInterval;
|
||||
Start();
|
||||
CheckState();
|
||||
}
|
||||
|
||||
Child *ChildSupervisor::GetDestination(const Message &aMessage) const
|
||||
@@ -147,7 +134,7 @@ void ChildSupervisor::HandleTimer(void)
|
||||
|
||||
for (uint8_t i = 0; i < numChildren; i++, child++)
|
||||
{
|
||||
if (!child->IsStateValidOrRestoring())
|
||||
if (child->GetState() != Child::kStateValid)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -166,6 +153,52 @@ exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void ChildSupervisor::CheckState(void)
|
||||
{
|
||||
bool shouldRun = false;
|
||||
uint8_t numChildren = 0;
|
||||
Mle::MleRouter &mle = GetInstance().Get<Mle::MleRouter>();
|
||||
|
||||
// Child Supervision should run if `mSupervisionInterval` is not
|
||||
// zero, Thread MLE operation is enabled, and there is at least one
|
||||
// "valid" child in the child table.
|
||||
|
||||
VerifyOrExit(mSupervisionInterval != 0);
|
||||
VerifyOrExit(mle.GetRole() != OT_DEVICE_ROLE_DISABLED);
|
||||
|
||||
for (Child *child = mle.GetChildren(&numChildren); numChildren > 0; child++, numChildren--)
|
||||
{
|
||||
VerifyOrExit(child->GetState() != Child::kStateValid, shouldRun = true);
|
||||
}
|
||||
|
||||
exit:
|
||||
|
||||
if (shouldRun && !mTimer.IsRunning())
|
||||
{
|
||||
mTimer.Start(kOneSecond);
|
||||
otLogInfoUtil(GetInstance(), "Starting Child Supervision");
|
||||
}
|
||||
|
||||
if (!shouldRun && mTimer.IsRunning())
|
||||
{
|
||||
mTimer.Stop();
|
||||
otLogInfoUtil(GetInstance(), "Stopping Child Supervision");
|
||||
}
|
||||
}
|
||||
|
||||
void ChildSupervisor::HandleStateChanged(Notifier::Callback &aCallback, uint32_t aFlags)
|
||||
{
|
||||
aCallback.GetOwner<ChildSupervisor>().HandleStateChanged(aFlags);
|
||||
}
|
||||
|
||||
void ChildSupervisor::HandleStateChanged(uint32_t aFlags)
|
||||
{
|
||||
if ((aFlags & (OT_CHANGED_THREAD_ROLE | OT_CHANGED_THREAD_CHILD_ADDED | OT_CHANGED_THREAD_CHILD_REMOVED)) != 0)
|
||||
{
|
||||
CheckState();
|
||||
}
|
||||
}
|
||||
|
||||
#endif // #if OPENTHREAD_FTD
|
||||
|
||||
SupervisionListener::SupervisionListener(Instance &aInstance)
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
|
||||
#include "common/locator.hpp"
|
||||
#include "common/message.hpp"
|
||||
#include "common/notifier.hpp"
|
||||
#include "common/timer.hpp"
|
||||
#include "mac/mac_frame.hpp"
|
||||
#include "thread/topology.hpp"
|
||||
@@ -155,11 +156,15 @@ private:
|
||||
};
|
||||
|
||||
void SendMessage(Child &aChild);
|
||||
void CheckState(void);
|
||||
static void HandleTimer(Timer &aTimer);
|
||||
void HandleTimer(void);
|
||||
static void HandleStateChanged(Notifier::Callback &aCallback, uint32_t aFlags);
|
||||
void HandleStateChanged(uint32_t aFlags);
|
||||
|
||||
uint16_t mSupervisionInterval;
|
||||
TimerMilli mTimer;
|
||||
uint16_t mSupervisionInterval;
|
||||
TimerMilli mTimer;
|
||||
Notifier::Callback mNotifierCallback;
|
||||
};
|
||||
|
||||
#else // #if OPENTHREAD_ENABLE_CHILD_SUPERVISION && OPENTHREAD_FTD
|
||||
|
||||
Reference in New Issue
Block a user