mirror of
https://github.com/espressif/openthread.git
synced 2026-08-11 05:07:47 +00:00
[mle] add mechanism to track current attach duration (#10923)
This commit adds a new mechanism to track the current attach time (the time duration since device was last attached to a Thread mesh). This duration indicates how long the device has been connected, regardless of its role(child, router, or leader). A related public OT API and CLI command are also added. This information can be used for debugging purposes and internally within the OT core to wait for the device to stabilize before enabling certain behaviors.
This commit is contained in:
@@ -52,7 +52,7 @@ extern "C" {
|
||||
*
|
||||
* @note This number versions both OpenThread platform and user APIs.
|
||||
*/
|
||||
#define OPENTHREAD_API_VERSION (465)
|
||||
#define OPENTHREAD_API_VERSION (466)
|
||||
|
||||
/**
|
||||
* @addtogroup api-instance
|
||||
|
||||
@@ -931,6 +931,23 @@ const otMleCounters *otThreadGetMleCounters(otInstance *aInstance);
|
||||
*/
|
||||
void otThreadResetMleCounters(otInstance *aInstance);
|
||||
|
||||
/**
|
||||
* Gets the current attach duration (number of seconds since the device last attached).
|
||||
*
|
||||
* Requires the `OPENTHREAD_CONFIG_UPTIME_ENABLE` feature.
|
||||
*
|
||||
* If the device is not currently attached, zero will be returned.
|
||||
*
|
||||
* Unlike the role-tracking variables in `otMleCounters`, which track the cumulative time the device is in each role,
|
||||
* this function tracks the time since the last successful attachment, indicating how long the device has been
|
||||
* connected to the Thread mesh (regardless of its role, whether acting as a child, router, or leader).
|
||||
*
|
||||
* @param[in] aInstance A pointer to an OpenThread instance.
|
||||
*
|
||||
* @returns The number of seconds since last attached.
|
||||
*/
|
||||
uint32_t otThreadGetCurrentAttachDuration(otInstance *aInstance);
|
||||
|
||||
/**
|
||||
* Pointer is called every time an MLE Parent Response message is received.
|
||||
*
|
||||
|
||||
@@ -21,6 +21,7 @@ Done
|
||||
|
||||
## OpenThread Command List
|
||||
|
||||
- [attachtime](#attachtime)
|
||||
- [ba](#ba)
|
||||
- [bbr](#bbr)
|
||||
- [br](README_BR.md)
|
||||
@@ -137,6 +138,20 @@ Done
|
||||
|
||||
## OpenThread Command Details
|
||||
|
||||
### attachtime
|
||||
|
||||
Prints the attach time (duration since device was last attached).
|
||||
|
||||
Requires `OPENTHREAD_CONFIG_UPTIME_ENABLE`.
|
||||
|
||||
Duration is formatted as `{hh}:{mm}:{ss}` for hours, minutes, and seconds if it is less than one day. If the duration is longer than one day, the format is `{dd}d.{hh}:{mm}:{ss}`.
|
||||
|
||||
```bash
|
||||
> attachtime
|
||||
01:38:25
|
||||
Done
|
||||
```
|
||||
|
||||
### bbr
|
||||
|
||||
Show current Primary Backbone Router information for Thread 1.2 device.
|
||||
|
||||
@@ -364,6 +364,34 @@ otError Interpreter::SetUserCommands(const otCliCommand *aCommands, uint8_t aLen
|
||||
|
||||
#if OPENTHREAD_FTD || OPENTHREAD_MTD
|
||||
|
||||
#if OPENTHREAD_CONFIG_UPTIME_ENABLE
|
||||
/**
|
||||
* @cli attachtime
|
||||
* @code
|
||||
* attachtime
|
||||
* 01:38:25
|
||||
* Done
|
||||
* @endcode
|
||||
* @par
|
||||
* Prints the current attach time (duration since device was last attached). Requires `OPENTHREAD_CONFIG_UPTIME_ENABLE`.
|
||||
* Duration is formatted as `{hh}:{mm}:{ss}` for hours, minutes, and seconds if it is less than one day. If the
|
||||
* duration is longer than one day, the format is `{dd}d.{hh}:{mm}:{ss}`.
|
||||
*/
|
||||
template <> otError Interpreter::Process<Cmd("attachtime")>(Arg aArgs[])
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
char string[OT_DURATION_STRING_SIZE];
|
||||
|
||||
VerifyOrExit(aArgs[0].IsEmpty(), error = OT_ERROR_INVALID_ARGS);
|
||||
|
||||
otConvertDurationInSecondsToString(otThreadGetCurrentAttachDuration(GetInstancePtr()), string, sizeof(string));
|
||||
OutputLine("%s", string);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_HISTORY_TRACKER_ENABLE
|
||||
template <> otError Interpreter::Process<Cmd("history")>(Arg aArgs[]) { return mHistory.Process(aArgs); }
|
||||
#endif
|
||||
@@ -8425,6 +8453,9 @@ otError Interpreter::ProcessCommand(Arg aArgs[])
|
||||
|
||||
static constexpr Command kCommands[] = {
|
||||
#if OPENTHREAD_FTD || OPENTHREAD_MTD
|
||||
#if OPENTHREAD_CONFIG_UPTIME_ENABLE
|
||||
CmdEntry("attachtime"),
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE
|
||||
CmdEntry("ba"),
|
||||
#endif
|
||||
|
||||
@@ -475,6 +475,13 @@ const otMleCounters *otThreadGetMleCounters(otInstance *aInstance)
|
||||
|
||||
void otThreadResetMleCounters(otInstance *aInstance) { AsCoreType(aInstance).Get<Mle::MleRouter>().ResetCounters(); }
|
||||
|
||||
#if OPENTHREAD_CONFIG_UPTIME_ENABLE
|
||||
uint32_t otThreadGetCurrentAttachDuration(otInstance *aInstance)
|
||||
{
|
||||
return AsCoreType(aInstance).Get<Mle::MleRouter>().GetCurrentAttachDuration();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_MLE_PARENT_RESPONSE_CALLBACK_API_ENABLE
|
||||
void otThreadRegisterParentResponseCallback(otInstance *aInstance,
|
||||
otThreadParentResponseCallback aCallback,
|
||||
|
||||
+22
-1
@@ -240,6 +240,15 @@ exit:
|
||||
}
|
||||
}
|
||||
|
||||
const Counters &Mle::GetCounters(void)
|
||||
{
|
||||
#if OPENTHREAD_CONFIG_UPTIME_ENABLE
|
||||
UpdateRoleTimeCounters(mRole);
|
||||
#endif
|
||||
|
||||
return mCounters;
|
||||
}
|
||||
|
||||
void Mle::ResetCounters(void)
|
||||
{
|
||||
ClearAllBytes(mCounters);
|
||||
@@ -249,6 +258,12 @@ void Mle::ResetCounters(void)
|
||||
}
|
||||
|
||||
#if OPENTHREAD_CONFIG_UPTIME_ENABLE
|
||||
|
||||
uint32_t Mle::GetCurrentAttachDuration(void) const
|
||||
{
|
||||
return IsAttached() ? Uptime::MsecToSec(Get<Uptime>().GetUptime()) - mLastAttachTime : 0;
|
||||
}
|
||||
|
||||
void Mle::UpdateRoleTimeCounters(DeviceRole aRole)
|
||||
{
|
||||
uint64_t currentUptimeMsec = Get<Uptime>().GetUptime();
|
||||
@@ -277,7 +292,8 @@ void Mle::UpdateRoleTimeCounters(DeviceRole aRole)
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_UPTIME_ENABLE
|
||||
|
||||
void Mle::SetRole(DeviceRole aRole)
|
||||
{
|
||||
@@ -288,6 +304,11 @@ void Mle::SetRole(DeviceRole aRole)
|
||||
LogNote("Role %s -> %s", RoleToString(oldRole), RoleToString(mRole));
|
||||
|
||||
#if OPENTHREAD_CONFIG_UPTIME_ENABLE
|
||||
if ((oldRole == kRoleDetached) && IsAttached())
|
||||
{
|
||||
mLastAttachTime = Uptime::MsecToSec(Get<Uptime>().GetUptime());
|
||||
}
|
||||
|
||||
UpdateRoleTimeCounters(oldRole);
|
||||
#endif
|
||||
|
||||
|
||||
+12
-8
@@ -598,19 +598,22 @@ public:
|
||||
*
|
||||
* @returns A reference to the MLE counters.
|
||||
*/
|
||||
const Counters &GetCounters(void)
|
||||
{
|
||||
#if OPENTHREAD_CONFIG_UPTIME_ENABLE
|
||||
UpdateRoleTimeCounters(mRole);
|
||||
#endif
|
||||
return mCounters;
|
||||
}
|
||||
const Counters &GetCounters(void);
|
||||
|
||||
/**
|
||||
* Resets the MLE counters.
|
||||
*/
|
||||
void ResetCounters(void);
|
||||
|
||||
#if OPENTHREAD_CONFIG_UPTIME_ENABLE
|
||||
/**
|
||||
* Determines the current attach duration (number of seconds since the device last attached).
|
||||
*
|
||||
* @returns Current attach duration in seconds.
|
||||
*/
|
||||
uint32_t GetCurrentAttachDuration(void) const;
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_MLE_PARENT_RESPONSE_CALLBACK_API_ENABLE
|
||||
/**
|
||||
* Registers the client callback that is called when processing an MLE Parent Response message.
|
||||
@@ -1477,10 +1480,11 @@ private:
|
||||
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
||||
uint32_t mCslTimeout;
|
||||
#endif
|
||||
uint64_t mAlternateTimestamp;
|
||||
#if OPENTHREAD_CONFIG_UPTIME_ENABLE
|
||||
uint32_t mLastAttachTime;
|
||||
uint64_t mLastUpdatedTimestamp;
|
||||
#endif
|
||||
uint64_t mAlternateTimestamp;
|
||||
|
||||
LeaderData mLeaderData;
|
||||
Parent mParent;
|
||||
|
||||
Reference in New Issue
Block a user