mirror of
https://github.com/espressif/openthread.git
synced 2026-08-02 09:07:47 +00:00
[mle-router] signal child/router entry being added or removed (#3838)
This commit updates the neighbor table callback to signal when either a child or a router neighbor entry is being added or removed. This change replaces and enhances the previous APIs relalted to child table callback.
This commit is contained in:
committed by
Jonathan Hui
parent
167362130c
commit
c0bc29197a
@@ -580,47 +580,55 @@ OTAPI int8_t OTCALL otThreadGetParentPriority(otInstance *aInstance);
|
||||
OTAPI otError OTCALL otThreadSetParentPriority(otInstance *aInstance, int8_t aParentPriority);
|
||||
|
||||
/**
|
||||
* This enumeration defines the constants used in `otThreadChildTableCallback` to indicate whether a child is added or
|
||||
* removed.
|
||||
* This enumeration defines the constants used in `otNeighborTableCallback` to indicate whether a child or router
|
||||
* neighbor is being added or removed.
|
||||
*
|
||||
*/
|
||||
typedef enum otThreadChildTableEvent
|
||||
typedef enum
|
||||
{
|
||||
OT_THREAD_CHILD_TABLE_EVENT_CHILD_ADDED, ///< A child is being added.
|
||||
OT_THREAD_CHILD_TABLE_EVENT_CHILD_REMOVED, ///< A child is being removed.
|
||||
} otThreadChildTableEvent;
|
||||
OT_NEIGHBOR_TABLE_EVENT_CHILD_ADDED, ///< A child is being added.
|
||||
OT_NEIGHBOR_TABLE_EVENT_CHILD_REMOVED, ///< A child is being removed.
|
||||
OT_NEIGHBOR_TABLE_EVENT_ROUTER_ADDED, ///< A router is being added.
|
||||
OT_NEIGHBOR_TABLE_EVENT_ROUTER_REMOVED, ///< A router is being removed.
|
||||
} otNeighborTableEvent;
|
||||
|
||||
/**
|
||||
* This function pointer is called to notify that a child is being added to or removed from child table.
|
||||
*
|
||||
* @param[in] aEvent A event flag indicating whether a child is being added or removed.
|
||||
* @param[in] aChildInfo A pointer to child information structure.
|
||||
* This type represent a neighbor table entry info (child or router) and is used as a parameter in the neighbor table
|
||||
* callback `otNeighborTableCallback`.
|
||||
*
|
||||
*/
|
||||
typedef void (*otThreadChildTableCallback)(otThreadChildTableEvent aEvent, const otChildInfo *aChildInfo);
|
||||
typedef struct
|
||||
{
|
||||
otInstance *mInstance; ///< The OpenThread instance.
|
||||
union
|
||||
{
|
||||
otChildInfo mChild; ///< The child neighbor info.
|
||||
otNeighborInfo mRouter; ///< The router neighbor info.
|
||||
} mInfo;
|
||||
} otNeighborTableEntryInfo;
|
||||
|
||||
/**
|
||||
* This function gets the child table callback function.
|
||||
* This function pointer is called to notify that a child or router neighbor is being added to or removed from neighbor
|
||||
* table.
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
*
|
||||
* @returns The callback function pointer.
|
||||
* @param[in] aEvent A event flag.
|
||||
* @param[in] aEntryInfo A pointer to table entry info.
|
||||
*
|
||||
*/
|
||||
otThreadChildTableCallback otThreadGetChildTableCallback(otInstance *aInstance);
|
||||
typedef void (*otNeighborTableCallback)(otNeighborTableEvent aEvent, const otNeighborTableEntryInfo *aEntryInfo);
|
||||
|
||||
/**
|
||||
* This function sets the child table callback function.
|
||||
* This function registers a neighbor table callback function.
|
||||
*
|
||||
* The provided callback (if non-NULL) will be invoked when a child entry is being added/removed to/from the child
|
||||
* table. Subsequent calls to this method will overwrite the previous callback. Note that this callback in invoked
|
||||
* while the child table is being updated and always before the `otStateChangedCallback`.
|
||||
* The provided callback (if non-NULL) will be invoked when a child or router neighbor entry is being added/removed
|
||||
* to/from the neighbor table. Subsequent calls to this method will overwrite the previous callback. Note that this
|
||||
* callback in invoked while the neighbor/child table is being updated and always before the `otStateChangedCallback`.
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
* @param[in] aCallback A pointer to callback handler function.
|
||||
*
|
||||
*/
|
||||
void otThreadSetChildTableCallback(otInstance *aInstance, otThreadChildTableCallback aCallback);
|
||||
void otThreadRegisterNeighborTableCallback(otInstance *aInstance, otNeighborTableCallback aCallback);
|
||||
|
||||
/**
|
||||
* @}
|
||||
|
||||
@@ -380,18 +380,11 @@ otError otThreadSetParentPriority(otInstance *aInstance, const int8_t aParentPri
|
||||
return instance.Get<Mle::MleRouter>().SetAssignParentPriority(aParentPriority);
|
||||
}
|
||||
|
||||
otThreadChildTableCallback otThreadGetChildTableCallback(otInstance *aInstance)
|
||||
void otThreadRegisterNeighborTableCallback(otInstance *aInstance, otNeighborTableCallback aCallback)
|
||||
{
|
||||
Instance &instance = *static_cast<Instance *>(aInstance);
|
||||
|
||||
return instance.Get<Mle::MleRouter>().GetChildTableChangedCallback();
|
||||
}
|
||||
|
||||
void otThreadSetChildTableCallback(otInstance *aInstance, otThreadChildTableCallback aCallback)
|
||||
{
|
||||
Instance &instance = *static_cast<Instance *>(aInstance);
|
||||
|
||||
instance.Get<Mle::MleRouter>().SetChildTableChangedCallback(aCallback);
|
||||
instance.Get<Mle::MleRouter>().RegisterNeighborTableChangedCallback(aCallback);
|
||||
}
|
||||
|
||||
#endif // OPENTHREAD_FTD
|
||||
|
||||
@@ -65,7 +65,7 @@ MleRouter::MleRouter(Instance &aInstance)
|
||||
, mAddressRelease(OT_URI_PATH_ADDRESS_RELEASE, &MleRouter::HandleAddressRelease, this)
|
||||
, mChildTable(aInstance)
|
||||
, mRouterTable(aInstance)
|
||||
, mChildTableChangedCallback(NULL)
|
||||
, mNeighborTableChangedCallback(NULL)
|
||||
, mChallengeTimeout(0)
|
||||
, mNextChildId(kMaxChildId)
|
||||
, mNetworkIdTimeout(kNetworkIdTimeout)
|
||||
@@ -984,6 +984,8 @@ otError MleRouter::HandleLinkAccept(const Message & aMessage,
|
||||
router->SetState(Neighbor::kStateValid);
|
||||
router->SetKeySequence(aKeySequence);
|
||||
|
||||
Signal(OT_NEIGHBOR_TABLE_EVENT_ROUTER_ADDED, *router);
|
||||
|
||||
if (aRequest)
|
||||
{
|
||||
// Challenge
|
||||
@@ -3157,7 +3159,7 @@ void MleRouter::RemoveNeighbor(Neighbor &aNeighbor)
|
||||
{
|
||||
if (aNeighbor.IsStateValidOrRestoring())
|
||||
{
|
||||
SignalChildUpdated(OT_THREAD_CHILD_TABLE_EVENT_CHILD_REMOVED, static_cast<Child &>(aNeighbor));
|
||||
Signal(OT_NEIGHBOR_TABLE_EVENT_CHILD_REMOVED, aNeighbor);
|
||||
}
|
||||
|
||||
aNeighbor.SetState(Neighbor::kStateInvalid);
|
||||
@@ -3175,6 +3177,7 @@ void MleRouter::RemoveNeighbor(Neighbor &aNeighbor)
|
||||
}
|
||||
else if (aNeighbor.GetState() == Neighbor::kStateValid)
|
||||
{
|
||||
Signal(OT_NEIGHBOR_TABLE_EVENT_ROUTER_REMOVED, aNeighbor);
|
||||
mRouterTable.RemoveNeighbor(static_cast<Router &>(aNeighbor));
|
||||
}
|
||||
|
||||
@@ -3632,6 +3635,26 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
void MleRouter::GetNeighborInfo(Neighbor &aNeighbor, otNeighborInfo &aNeighInfo)
|
||||
{
|
||||
aNeighInfo.mExtAddress = aNeighbor.GetExtAddress();
|
||||
aNeighInfo.mAge = TimerMilli::MsecToSec(TimerMilli::Elapsed(aNeighbor.GetLastHeard()));
|
||||
aNeighInfo.mRloc16 = aNeighbor.GetRloc16();
|
||||
aNeighInfo.mLinkFrameCounter = aNeighbor.GetLinkFrameCounter();
|
||||
aNeighInfo.mMleFrameCounter = aNeighbor.GetMleFrameCounter();
|
||||
aNeighInfo.mLinkQualityIn = aNeighbor.GetLinkInfo().GetLinkQuality();
|
||||
aNeighInfo.mAverageRssi = aNeighbor.GetLinkInfo().GetAverageRss();
|
||||
aNeighInfo.mLastRssi = aNeighbor.GetLinkInfo().GetLastRss();
|
||||
#if OPENTHREAD_CONFIG_ENABLE_TX_ERROR_RATE_TRACKING
|
||||
aNeighInfo.mFrameErrorRate = aNeighbor.GetLinkInfo().GetFrameErrorRate();
|
||||
aNeighInfo.mMessageErrorRate = aNeighbor.GetLinkInfo().GetMessageErrorRate();
|
||||
#endif
|
||||
aNeighInfo.mRxOnWhenIdle = aNeighbor.IsRxOnWhenIdle();
|
||||
aNeighInfo.mSecureDataRequest = aNeighbor.IsSecureDataRequest();
|
||||
aNeighInfo.mFullThreadDevice = aNeighbor.IsFullThreadDevice();
|
||||
aNeighInfo.mFullNetworkData = aNeighbor.IsFullNetworkData();
|
||||
}
|
||||
|
||||
otError MleRouter::GetNextNeighborInfo(otNeighborInfoIterator &aIterator, otNeighborInfo &aNeighInfo)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
@@ -3689,22 +3712,7 @@ exit:
|
||||
|
||||
if (neighbor != NULL)
|
||||
{
|
||||
aNeighInfo.mExtAddress = neighbor->GetExtAddress();
|
||||
aNeighInfo.mAge = TimerMilli::MsecToSec(TimerMilli::Elapsed(neighbor->GetLastHeard()));
|
||||
aNeighInfo.mRloc16 = neighbor->GetRloc16();
|
||||
aNeighInfo.mLinkFrameCounter = neighbor->GetLinkFrameCounter();
|
||||
aNeighInfo.mMleFrameCounter = neighbor->GetMleFrameCounter();
|
||||
aNeighInfo.mLinkQualityIn = neighbor->GetLinkInfo().GetLinkQuality();
|
||||
aNeighInfo.mAverageRssi = neighbor->GetLinkInfo().GetAverageRss();
|
||||
aNeighInfo.mLastRssi = neighbor->GetLinkInfo().GetLastRss();
|
||||
#if OPENTHREAD_CONFIG_ENABLE_TX_ERROR_RATE_TRACKING
|
||||
aNeighInfo.mFrameErrorRate = neighbor->GetLinkInfo().GetFrameErrorRate();
|
||||
aNeighInfo.mMessageErrorRate = neighbor->GetLinkInfo().GetMessageErrorRate();
|
||||
#endif
|
||||
aNeighInfo.mRxOnWhenIdle = neighbor->IsRxOnWhenIdle();
|
||||
aNeighInfo.mSecureDataRequest = neighbor->IsSecureDataRequest();
|
||||
aNeighInfo.mFullThreadDevice = neighbor->IsFullThreadDevice();
|
||||
aNeighInfo.mFullNetworkData = neighbor->IsFullNetworkData();
|
||||
GetNeighborInfo(*neighbor, aNeighInfo);
|
||||
}
|
||||
|
||||
return error;
|
||||
@@ -4547,7 +4555,7 @@ void MleRouter::SetChildStateToValid(Child &aChild)
|
||||
|
||||
aChild.SetState(Neighbor::kStateValid);
|
||||
StoreChild(aChild);
|
||||
SignalChildUpdated(OT_THREAD_CHILD_TABLE_EVENT_CHILD_ADDED, aChild);
|
||||
Signal(OT_NEIGHBOR_TABLE_EVENT_CHILD_ADDED, aChild);
|
||||
|
||||
exit:
|
||||
return;
|
||||
@@ -4621,28 +4629,44 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
void MleRouter::SignalChildUpdated(otThreadChildTableEvent aEvent, Child &aChild)
|
||||
void MleRouter::Signal(otNeighborTableEvent aEvent, Neighbor &aNeighbor)
|
||||
{
|
||||
if (mChildTableChangedCallback != NULL)
|
||||
if (mNeighborTableChangedCallback != NULL)
|
||||
{
|
||||
otChildInfo childInfo;
|
||||
otError error;
|
||||
otNeighborTableEntryInfo info;
|
||||
otError error;
|
||||
|
||||
error = GetChildInfo(aChild, childInfo);
|
||||
assert(error == OT_ERROR_NONE);
|
||||
info.mInstance = &GetInstance();
|
||||
|
||||
mChildTableChangedCallback(aEvent, &childInfo);
|
||||
switch (aEvent)
|
||||
{
|
||||
case OT_NEIGHBOR_TABLE_EVENT_CHILD_ADDED:
|
||||
case OT_NEIGHBOR_TABLE_EVENT_CHILD_REMOVED:
|
||||
error = GetChildInfo(static_cast<Child &>(aNeighbor), info.mInfo.mChild);
|
||||
assert(error == OT_ERROR_NONE);
|
||||
break;
|
||||
|
||||
case OT_NEIGHBOR_TABLE_EVENT_ROUTER_ADDED:
|
||||
case OT_NEIGHBOR_TABLE_EVENT_ROUTER_REMOVED:
|
||||
GetNeighborInfo(aNeighbor, info.mInfo.mRouter);
|
||||
break;
|
||||
}
|
||||
|
||||
mNeighborTableChangedCallback(aEvent, &info);
|
||||
}
|
||||
|
||||
switch (aEvent)
|
||||
{
|
||||
case OT_THREAD_CHILD_TABLE_EVENT_CHILD_ADDED:
|
||||
case OT_NEIGHBOR_TABLE_EVENT_CHILD_ADDED:
|
||||
Get<Notifier>().Signal(OT_CHANGED_THREAD_CHILD_ADDED);
|
||||
break;
|
||||
|
||||
case OT_THREAD_CHILD_TABLE_EVENT_CHILD_REMOVED:
|
||||
case OT_NEIGHBOR_TABLE_EVENT_CHILD_REMOVED:
|
||||
Get<Notifier>().Signal(OT_CHANGED_THREAD_CHILD_REMOVED);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -597,23 +597,27 @@ public:
|
||||
otError GetMaxChildTimeout(uint32_t &aTimeout) const;
|
||||
|
||||
/**
|
||||
* This method sets the "child table changed" callback function.
|
||||
* This method register the "neighbor table changed" callback function.
|
||||
*
|
||||
* The provided callback (if non-NULL) will be invoked when a child entry is being added/remove to/from the child
|
||||
* table. Subsequent calls to this method will overwrite the previous callback.
|
||||
* The provided callback (if non-NULL) 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 SetChildTableChangedCallback(otThreadChildTableCallback aCallback) { mChildTableChangedCallback = aCallback; }
|
||||
void RegisterNeighborTableChangedCallback(otNeighborTableCallback aCallback)
|
||||
{
|
||||
mNeighborTableChangedCallback = aCallback;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method gets the "child table changed" callback function.
|
||||
* This method signals a "neighbor table changed" events (invoking the registered callback function).
|
||||
*
|
||||
* @returns The callback function pointer.
|
||||
* @param[in] aEvent The event to emit (child/router added/removed).
|
||||
* @param[in] aNeighbor The neighbor that is being added/removed.
|
||||
*
|
||||
*/
|
||||
otThreadChildTableCallback GetChildTableChangedCallback(void) const { return mChildTableChangedCallback; }
|
||||
void Signal(otNeighborTableEvent aEvent, Neighbor &aNeighbor);
|
||||
|
||||
/**
|
||||
* This method returns whether the device has any sleepy children subscribed the address.
|
||||
@@ -679,6 +683,7 @@ private:
|
||||
otError AppendActiveDataset(Message &aMessage);
|
||||
otError AppendPendingDataset(Message &aMessage);
|
||||
otError GetChildInfo(Child &aChild, otChildInfo &aChildInfo);
|
||||
void GetNeighborInfo(Neighbor &aNeighbor, otNeighborInfo &aNeighInfo);
|
||||
otError RefreshStoredChildren(void);
|
||||
void HandleDetachStart(void);
|
||||
otError HandleChildStart(AttachMode aMode);
|
||||
@@ -766,8 +771,6 @@ private:
|
||||
static void HandleStateUpdateTimer(Timer &aTimer);
|
||||
void HandleStateUpdateTimer(void);
|
||||
|
||||
void SignalChildUpdated(otThreadChildTableEvent aEvent, Child &aChild);
|
||||
|
||||
TrickleTimer mAdvertiseTimer;
|
||||
TimerMilli mStateUpdateTimer;
|
||||
|
||||
@@ -777,7 +780,7 @@ private:
|
||||
ChildTable mChildTable;
|
||||
RouterTable mRouterTable;
|
||||
|
||||
otThreadChildTableCallback mChildTableChangedCallback;
|
||||
otNeighborTableCallback mNeighborTableChangedCallback;
|
||||
|
||||
uint8_t mChallengeTimeout;
|
||||
uint8_t mChallenge[8];
|
||||
|
||||
@@ -101,7 +101,14 @@ void RouterTable::ClearNeighbors(void)
|
||||
{
|
||||
for (uint8_t index = 0; index < Mle::kMaxRouters; index++)
|
||||
{
|
||||
mRouters[index].SetState(Neighbor::kStateInvalid);
|
||||
Router &router = mRouters[index];
|
||||
|
||||
if (router.GetState() == Neighbor::kStateValid)
|
||||
{
|
||||
Get<Mle::MleRouter>().Signal(OT_NEIGHBOR_TABLE_EVENT_ROUTER_REMOVED, router);
|
||||
}
|
||||
|
||||
router.SetState(Neighbor::kStateInvalid);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -274,7 +274,7 @@ NcpBase::NcpBase(Instance *aInstance)
|
||||
#endif
|
||||
otIcmp6SetEchoMode(mInstance, OT_ICMP6_ECHO_HANDLER_DISABLED);
|
||||
#if OPENTHREAD_FTD
|
||||
otThreadSetChildTableCallback(mInstance, &NcpBase::HandleChildTableChanged);
|
||||
otThreadRegisterNeighborTableCallback(mInstance, &NcpBase::HandleNeighborTableChanged);
|
||||
#if OPENTHREAD_CONFIG_ENABLE_STEERING_DATA_SET_OOB
|
||||
memset(&mSteeringDataAddress, 0, sizeof(mSteeringDataAddress));
|
||||
#endif
|
||||
|
||||
@@ -276,8 +276,8 @@ protected:
|
||||
void HandleTimeSyncUpdate(void);
|
||||
|
||||
#if OPENTHREAD_FTD
|
||||
static void HandleChildTableChanged(otThreadChildTableEvent aEvent, const otChildInfo *aChildInfo);
|
||||
void HandleChildTableChanged(otThreadChildTableEvent aEvent, const otChildInfo &aChildInfo);
|
||||
static void HandleNeighborTableChanged(otNeighborTableEvent aEvent, const otNeighborTableEntryInfo *aEntry);
|
||||
void HandleNeighborTableChanged(otNeighborTableEvent aEvent, const otNeighborTableEntryInfo &aEntry);
|
||||
|
||||
static void HandleParentResponseInfo(otThreadParentResponseInfo *aInfo, void *aContext);
|
||||
void HandleParentResponseInfo(const otThreadParentResponseInfo &aInfo);
|
||||
|
||||
@@ -115,12 +115,12 @@ exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void NcpBase::HandleChildTableChanged(otThreadChildTableEvent aEvent, const otChildInfo *aChildInfo)
|
||||
void NcpBase::HandleNeighborTableChanged(otNeighborTableEvent aEvent, const otNeighborTableEntryInfo *aEntry)
|
||||
{
|
||||
GetNcpInstance()->HandleChildTableChanged(aEvent, *aChildInfo);
|
||||
GetNcpInstance()->HandleNeighborTableChanged(aEvent, *aEntry);
|
||||
}
|
||||
|
||||
void NcpBase::HandleChildTableChanged(otThreadChildTableEvent aEvent, const otChildInfo &aChildInfo)
|
||||
void NcpBase::HandleNeighborTableChanged(otNeighborTableEvent aEvent, const otNeighborTableEntryInfo &aEntry)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
uint8_t header = SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0;
|
||||
@@ -128,15 +128,15 @@ void NcpBase::HandleChildTableChanged(otThreadChildTableEvent aEvent, const otCh
|
||||
|
||||
VerifyOrExit(!mChangedPropsSet.IsPropertyFiltered(SPINEL_PROP_THREAD_CHILD_TABLE));
|
||||
|
||||
VerifyOrExit(!aChildInfo.mIsStateRestoring);
|
||||
VerifyOrExit(!aEntry.mInfo.mChild.mIsStateRestoring);
|
||||
|
||||
switch (aEvent)
|
||||
{
|
||||
case OT_THREAD_CHILD_TABLE_EVENT_CHILD_ADDED:
|
||||
case OT_NEIGHBOR_TABLE_EVENT_CHILD_ADDED:
|
||||
command = SPINEL_CMD_PROP_VALUE_INSERTED;
|
||||
break;
|
||||
|
||||
case OT_THREAD_CHILD_TABLE_EVENT_CHILD_REMOVED:
|
||||
case OT_NEIGHBOR_TABLE_EVENT_CHILD_REMOVED:
|
||||
command = SPINEL_CMD_PROP_VALUE_REMOVED;
|
||||
break;
|
||||
|
||||
@@ -145,7 +145,7 @@ void NcpBase::HandleChildTableChanged(otThreadChildTableEvent aEvent, const otCh
|
||||
}
|
||||
|
||||
SuccessOrExit(error = mEncoder.BeginFrame(header, command, SPINEL_PROP_THREAD_CHILD_TABLE));
|
||||
SuccessOrExit(error = EncodeChildInfo(aChildInfo));
|
||||
SuccessOrExit(error = EncodeChildInfo(aEntry.mInfo.mChild));
|
||||
SuccessOrExit(error = mEncoder.EndFrame());
|
||||
|
||||
exit:
|
||||
|
||||
Reference in New Issue
Block a user