Skip to content

Commit

Permalink
update as comments suggested
Browse files Browse the repository at this point in the history
  • Loading branch information
Irving-cl committed Sep 1, 2023
1 parent b29fce9 commit ae301ea
Show file tree
Hide file tree
Showing 6 changed files with 138 additions and 143 deletions.
2 changes: 1 addition & 1 deletion include/openthread/instance.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ extern "C" {
* @note This number versions both OpenThread platform and user APIs.
*
*/
#define OPENTHREAD_API_VERSION (355)
#define OPENTHREAD_API_VERSION (356)

/**
* @addtogroup api-instance
Expand Down
8 changes: 4 additions & 4 deletions include/openthread/link_metrics.h
Original file line number Diff line number Diff line change
Expand Up @@ -261,11 +261,11 @@ void otLinkMetricsManagerSetEnabled(otInstance *aInstance, bool aEnable);
/**
* Get Link Metrics data of a neighbor by its extended address.
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aExtAddress A pointer to the Mac extended address of the Probing Subject.
* @param[out] aLinkMetricsValues A pointer to the Link Metrics values of the subject.
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aExtAddress A pointer to the Mac extended address of the Probing Subject.
* @param[out] aLinkMetricsValues A pointer to the Link Metrics values of the subject.
*
* @retval OT_ERROR_NONE Successfully got the Link Metrics data
* @retval OT_ERROR_NONE Successfully got the Link Metrics data.
* @retval OT_ERROR_INVALID_ARGS The arguments are invalid.
* @retval OT_ERROR_NOT_FOUND No neighbor with the given extended address is found.
*
Expand Down
6 changes: 3 additions & 3 deletions src/cli/cli.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3880,7 +3880,7 @@ template <> otError Interpreter::Process<Cmd("linkmetricsmgr")>(Arg aArgs[])
* linkmetricmgr disable
* Done
* @endcode
* @cparam nat64 @ca{enable|disable}
* @cparam linkmetricsmgr @ca{enable|disable}
* @par api_copy
* #otLinkMetricsManagerSetEnabled
*
Expand All @@ -3895,8 +3895,8 @@ template <> otError Interpreter::Process<Cmd("linkmetricsmgr")>(Arg aArgs[])
* ExtAddr:827aa7f7f63e1234, LinkMargin:80, Rssi:-20
* Done
* @endcode
* @par
* Show the link metrics data of all the subjects.
* @api_copy
* #otLinkMetricsManagerGetMetricsValueByExtAddr
*
*/
else if (aArgs[0] == "show")
Expand Down
222 changes: 103 additions & 119 deletions src/core/utils/link_metrics_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,41 +139,24 @@ void LinkMetricsManager::UpdateSubjects(void)
{
Subject *subject = mPool.Allocate();

if (subject != nullptr)
{
subject->Clear();
subject->mExtAddress = AsCoreType(&neighborInfo.mExtAddress);
IgnoreError(mSubjectList.Add(*subject));
}
VerifyOrExit(subject != nullptr);

subject->Clear();
subject->mExtAddress = AsCoreType(&neighborInfo.mExtAddress);
IgnoreError(mSubjectList.Add(*subject));
}
}

exit:
return;
}

// This method updates the state and take corresponding actions for all subjects and removes stale subjects.
void LinkMetricsManager::UpdateLinkMetricsStates(void)
{
ot::LinkedList<Subject> staleSubjects;

Subject *entry;
Subject *prev;
Subject *next;
LinkedList<Subject> staleSubjects;

for (prev = nullptr, entry = mSubjectList.GetHead(); entry != nullptr; entry = next)
{
Error error = UpdateStateForSingleSubject(*entry);

next = entry->GetNext();

if (error == kErrorUnknownNeighbor || error == kErrorNotCapable)
{
mSubjectList.PopAfter(prev);
IgnoreError(staleSubjects.Add(*entry));
}
else
{
prev = entry;
}
}
mSubjectList.RemoveAllMatching(*this, staleSubjects);

while (!staleSubjects.IsEmpty())
{
Expand All @@ -187,7 +170,7 @@ void LinkMetricsManager::UnregisterAllSubjects(void)
{
for (Subject &subject : mSubjectList)
{
IgnoreError(UnregisterEapForSingleSubject(subject));
IgnoreError(subject.UnregisterEap(GetInstance()));
}
}

Expand All @@ -201,96 +184,6 @@ void LinkMetricsManager::ReleaseAllSubjects(void)
}
}

Error LinkMetricsManager::UpdateStateForSingleSubject(Subject &aSubject)
{
bool shouldConfigure = false;
uint32_t pastTimeMs;
Error error = kErrorNone;

switch (aSubject.mState)
{
case kNotConfigured:
case kConfiguring:
case kRenewing:
if (aSubject.mAttempts >= kConfigureLinkMetricsMaxAttempts)
{
aSubject.mState = kNotSupported;
}
else
{
shouldConfigure = true;
}
break;
case kActive:
pastTimeMs = TimerMilli::GetNow() - aSubject.mLastUpdateTime;
if (pastTimeMs >= kStateUpdateIntervalMilliSec)
{
shouldConfigure = true;
}
break;
case kNotSupported:
ExitNow(error = kErrorNotCapable);
break;
default:
break;
}

if (shouldConfigure)
{
error = ConfigureEapForSingleSubject(aSubject);
}

exit:
return error;
}

Error LinkMetricsManager::ConfigureEapForSingleSubject(Subject &aSubject)
{
Error error = kErrorNone;
Neighbor *neighbor = Get<NeighborTable>().FindNeighbor(aSubject.mExtAddress);
Ip6::Address destination;
LinkMetrics::EnhAckFlags enhAckFlags = LinkMetrics::kEnhAckRegister;
LinkMetrics::Metrics metricsFlags;

VerifyOrExit(neighbor != nullptr, error = kErrorUnknownNeighbor);
destination.SetToLinkLocalAddress(neighbor->GetExtAddress());

metricsFlags.Clear();
metricsFlags.mLinkMargin = 1;
metricsFlags.mRssi = 1;
error = Get<LinkMetrics::Initiator>().SendMgmtRequestEnhAckProbing(destination, enhAckFlags, &metricsFlags);

aSubject.mAttempts++;
exit:
if (error == kErrorNone)
{
if (aSubject.mState == SubjectState::kActive)
{
aSubject.mState = SubjectState::kRenewing;
}
else
{
aSubject.mState = SubjectState::kConfiguring;
}
}
return error;
}

Error LinkMetricsManager::UnregisterEapForSingleSubject(Subject &aSubject)
{
Error error = kErrorNone;
Neighbor *neighbor = Get<NeighborTable>().FindNeighbor(aSubject.mExtAddress);
Ip6::Address destination;
LinkMetrics::EnhAckFlags enhAckFlags = LinkMetrics::kEnhAckClear;

VerifyOrExit(neighbor != nullptr, error = kErrorUnknownNeighbor);
destination.SetToLinkLocalAddress(neighbor->GetExtAddress());

error = Get<LinkMetrics::Initiator>().SendMgmtRequestEnhAckProbing(destination, enhAckFlags, nullptr);
exit:
return error;
}

void LinkMetricsManager::HandleNotifierEvents(Events aEvents)
{
if (aEvents.Contains(kEventThreadRoleChanged))
Expand Down Expand Up @@ -379,7 +272,98 @@ void LinkMetricsManager::HandleEnhAckIe(otShortAddress aShortAddress
{
LogWarn("Metrics received are unexpected!");
}
return;
}

// This special Match method is used for "iterating over list while removing some items"
bool LinkMetricsManager::Subject::Matches(const LinkMetricsManager &aLinkMetricsMgr)
{
Error error = UpdateState(aLinkMetricsMgr.GetInstance());

return error == kErrorUnknownNeighbor || error == kErrorNotCapable;
}

Error LinkMetricsManager::Subject::ConfigureEap(Instance &aInstance)
{
Error error = kErrorNone;
Neighbor *neighbor = aInstance.Get<NeighborTable>().FindNeighbor(mExtAddress);
Ip6::Address destination;
LinkMetrics::EnhAckFlags enhAckFlags = LinkMetrics::kEnhAckRegister;
LinkMetrics::Metrics metricsFlags;

VerifyOrExit(neighbor != nullptr, error = kErrorUnknownNeighbor);
destination.SetToLinkLocalAddress(neighbor->GetExtAddress());

metricsFlags.Clear();
metricsFlags.mLinkMargin = 1;
metricsFlags.mRssi = 1;
error =
aInstance.Get<LinkMetrics::Initiator>().SendMgmtRequestEnhAckProbing(destination, enhAckFlags, &metricsFlags);

exit:
if (error == kErrorNone)
{
mState = (mState == SubjectState::kActive) ? SubjectState::kRenewing : SubjectState::kConfiguring;
mAttempts++;
}
return error;
}

Error LinkMetricsManager::Subject::UnregisterEap(Instance &aInstance)
{
Error error = kErrorNone;
Neighbor *neighbor = aInstance.Get<NeighborTable>().FindNeighbor(mExtAddress);
Ip6::Address destination;
LinkMetrics::EnhAckFlags enhAckFlags = LinkMetrics::kEnhAckClear;

VerifyOrExit(neighbor != nullptr, error = kErrorUnknownNeighbor);
destination.SetToLinkLocalAddress(neighbor->GetExtAddress());

error = aInstance.Get<LinkMetrics::Initiator>().SendMgmtRequestEnhAckProbing(destination, enhAckFlags, nullptr);
exit:
return error;
}

Error LinkMetricsManager::Subject::UpdateState(Instance &aInstance)
{
bool shouldConfigure = false;
uint32_t pastTimeMs;
Error error = kErrorNone;

switch (mState)
{
case kNotConfigured:
case kConfiguring:
case kRenewing:
if (mAttempts >= kConfigureLinkMetricsMaxAttempts)
{
mState = kNotSupported;
}
else
{
shouldConfigure = true;
}
break;
case kActive:
pastTimeMs = TimerMilli::GetNow() - mLastUpdateTime;
if (pastTimeMs >= kStateUpdateIntervalMilliSec)
{
shouldConfigure = true;
}
break;
case kNotSupported:
ExitNow(error = kErrorNotCapable);
break;
default:
break;
}

if (shouldConfigure)
{
error = ConfigureEap(aInstance);
}

exit:
return error;
}

/**
Expand Down
40 changes: 24 additions & 16 deletions src/core/utils/link_metrics_manager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,9 @@ namespace Utils {
/**
*
* Link Metrics Manager feature utilizes the Enhanced-ACK Based
* Probing to get the Link Metrics data of neighboring devices.
* It is a user of the Link Metrics feature.
* Probing (abbreviated as "EAP" below) to get the Link Metrics
* data of neighboring devices. It is a user of the Link Metrics
* feature.
*
* The feature works as follow:
* - Start/Stop
Expand All @@ -78,7 +79,8 @@ namespace Utils {
*
* A CLI interface is provided to enable/disable this feature.
*
* Once enabled, it will regularly check current neighbors
* Once enabled, it will regularly check current neighbors (all
* devices in the neighbor table, including 'Child' and 'Router')
* and configure the probing with them if haven't done that.
* If disabled, it will clear the configuration with its subjects
* and the local data.
Expand All @@ -90,7 +92,7 @@ namespace Utils {
* EAP with the subject again.
* The manager may find that some subject (neighbor) no longer
* exist when trying to configure EAP. It will remove the stale
* subject.
* subject then.
*
* - Show data
* An OT API is provided to get the link metrics data of any
Expand Down Expand Up @@ -133,6 +135,11 @@ class LinkMetricsManager : public InstanceLocator, private NonCopyable
Subject *mNext;

bool Matches(const Mac::ExtAddress &aExtAddress) const { return mExtAddress == aExtAddress; }
bool Matches(const LinkMetricsManager &aLinkMetricsMgr);

Error ConfigureEap(Instance &aInstance);
Error UnregisterEap(Instance &aInstance);
Error UpdateState(Instance &aInstance);
};

public:
Expand Down Expand Up @@ -169,18 +176,19 @@ class LinkMetricsManager : public InstanceLocator, private NonCopyable
static constexpr uint16_t kTimeBeforeStartMilliSec = 5000;
static constexpr uint32_t kStateUpdateIntervalMilliSec = 150000;
static constexpr uint8_t kConfigureLinkMetricsMaxAttempts = 3;
static constexpr uint8_t kMaximumSubjectToTrack = 128;

void Start(void);
void Stop(void);
void Update(void);
void UpdateSubjects(void);
void UpdateLinkMetricsStates(void);
void UnregisterAllSubjects(void);
void ReleaseAllSubjects(void);
Error UpdateStateForSingleSubject(Subject &aSubject);
Error ConfigureEapForSingleSubject(Subject &aSubject);
Error UnregisterEapForSingleSubject(Subject &aSubject);
#if OPENTHREAD_FTD
static constexpr uint8_t kMaximumSubjectToTrack = 128;
#elif OPENTHREAD_MTD
static constexpr uint8_t kMaximumSubjectToTrack = 1;
#endif

void Start(void);
void Stop(void);
void Update(void);
void UpdateSubjects(void);
void UpdateLinkMetricsStates(void);
void UnregisterAllSubjects(void);
void ReleaseAllSubjects(void);

void HandleNotifierEvents(Events aEvents);
void HandleTimer(void);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@
ROUTER = 2
CHILD = 3
"""
Acronyms:
- EAP - Enhanced-ACK Based Probing
Test Process:
1. Initiate a leader and a router at the beginning.
2. Enable Link Metrics Manager on leader.
Expand Down

0 comments on commit ae301ea

Please sign in to comment.