From 144a4e3e06daa2ea9ed10f2554ac1845efe8016f Mon Sep 17 00:00:00 2001 From: Abtin Keshavarzian Date: Fri, 7 Sep 2018 00:01:31 -0700 Subject: [PATCH] [mle] add MLE counters (#2982) This commit adds support for a set of MLE counters (e.g., counters to track number of times device entered different roles, or counters tracking number of attach attempts, partition ID or parent changes). --- include/openthread/thread.h | 47 +++++++++++++++++++++++++++++++++++++ src/core/api/thread_api.cpp | 14 +++++++++++ src/core/thread/mle.cpp | 30 +++++++++++++++++++++++ src/core/thread/mle.hpp | 16 +++++++++++++ 4 files changed, 107 insertions(+) diff --git a/include/openthread/thread.h b/include/openthread/thread.h index 9c2bbae71..33e09bf88 100644 --- a/include/openthread/thread.h +++ b/include/openthread/thread.h @@ -153,6 +153,35 @@ typedef struct otIpCounters uint32_t mRxFailure; ///< The number of IPv6 packets failed to receive. } otIpCounters; +/** + * This structure represents the Thread MLE counters. + * + */ +typedef struct otMleCounters +{ + uint16_t mDisabledRole; ///< Number of times device entered OT_DEVICE_ROLE_DISABLED role. + uint16_t mDetachedRole; ///< Number of times device entered OT_DEVICE_ROLE_DETACHED role. + uint16_t mChildRole; ///< Number of times device entered OT_DEVICE_ROLE_CHILD role. + uint16_t mRouterRole; ///< Number of times device entered OT_DEVICE_ROLE_ROUTER role. + uint16_t mLeaderRole; ///< Number of times device entered OT_DEVICE_ROLE_LEADER role. + uint16_t mAttachAttempts; ///< Number of attach attempts while device was detached. + uint16_t mParitionIdChanges; ///< Number of changes to partition ID. + uint16_t mBetterPartitionAttachAttempts; ///< Number of attempts to attach to a better partition. + + /** + * Number of times device changed its parents. + * + * Support for this counter requires the feature option OPENTHREAD_CONFIG_INFORM_PREVIOUS_PARENT_ON_REATTACH to be + * enabled. + * + * A parent change can happen if device detaches from its current parent and attaches to a different one, or even + * while device is attached when the periodic parent search feature is enabled (please see option + * OPENTHREAD_CONFIG_ENABLE_PERIODIC_PARENT_SEARCH). + * + */ + uint16_t mParentChanges; +} otMleCounters; + /** * This function starts Thread protocol operation. * @@ -670,6 +699,24 @@ OTAPI otError OTCALL otThreadSendDiagnosticReset(otInstance * aInstance, */ OTAPI const otIpCounters *OTCALL otThreadGetIp6Counters(otInstance *aInstance); +/** + * Get the Thread MLE counters. + * + * @param[in] aInstance A pointer to an OpenThread instance. + * + * @returns A pointer to the Thread MLE counters. + * + */ +const otMleCounters *otThreadGetMleCounters(otInstance *aInstance); + +/** + * Reset the Thread MLE counters. + * + * @param[in] aInstance A pointer to an OpenThread instance. + * + */ +void otThreadResetMleCounters(otInstance *aInstance); + /** * @} * diff --git a/src/core/api/thread_api.cpp b/src/core/api/thread_api.cpp index d76612721..4eb346711 100644 --- a/src/core/api/thread_api.cpp +++ b/src/core/api/thread_api.cpp @@ -524,3 +524,17 @@ const otIpCounters *otThreadGetIp6Counters(otInstance *aInstance) return &instance.GetThreadNetif().GetMeshForwarder().GetCounters(); } + +const otMleCounters *otThreadGetMleCounters(otInstance *aInstance) +{ + Instance &instance = *static_cast(aInstance); + + return &instance.GetThreadNetif().GetMle().GetCounters(); +} + +void otThreadResetMleCounters(otInstance *aInstance) +{ + Instance &instance = *static_cast(aInstance); + + instance.GetThreadNetif().GetMle().ResetCounters(); +} diff --git a/src/core/thread/mle.cpp b/src/core/thread/mle.cpp index ff6c18511..29e0e2d12 100644 --- a/src/core/thread/mle.cpp +++ b/src/core/thread/mle.cpp @@ -123,6 +123,7 @@ Mle::Mle(Instance &aInstance) memset(&mRealmLocalAllThreadNodes, 0, sizeof(mRealmLocalAllThreadNodes)); memset(&mLeaderAloc, 0, sizeof(mLeaderAloc)); memset(&mParentCandidate, 0, sizeof(mParentCandidate)); + ResetCounters(); // link-local 64 mLinkLocal64.GetAddress().mFields.m16[0] = HostSwap16(0xfe80); @@ -304,6 +305,26 @@ void Mle::SetRole(otDeviceRole aRole) mRole = aRole; GetNotifier().Signal(OT_CHANGED_THREAD_ROLE); + + switch (mRole) + { + case OT_DEVICE_ROLE_DISABLED: + mCounters.mDisabledRole++; + break; + case OT_DEVICE_ROLE_DETACHED: + mCounters.mDetachedRole++; + break; + case OT_DEVICE_ROLE_CHILD: + mCounters.mChildRole++; + break; + case OT_DEVICE_ROLE_ROUTER: + mCounters.mRouterRole++; + break; + case OT_DEVICE_ROLE_LEADER: + mCounters.mLeaderRole++; + break; + } + #if OPENTHREAD_ENABLE_BORDER_AGENT // Start border agent if (aRole == OT_DEVICE_ROLE_ROUTER || aRole == OT_DEVICE_ROLE_LEADER || aRole == OT_DEVICE_ROLE_CHILD) @@ -595,6 +616,10 @@ otError Mle::BecomeChild(AttachMode aMode) netif.GetMle().StopAdvertiseTimer(); } } + else + { + mCounters.mBetterPartitionAttachAttempts++; + } mAttachTimer.Start(GetAttachStartDelay()); @@ -607,6 +632,8 @@ otError Mle::BecomeChild(AttachMode aMode) mAttachCounter--; } + mCounters.mAttachAttempts++; + if (!IsRxOnWhenIdle()) { netif.GetMac().SetRxOnWhenIdle(false); @@ -923,6 +950,7 @@ void Mle::SetLeaderData(uint32_t aPartitionId, uint8_t aWeighting, uint8_t aLead { GetNetif().GetMle().HandlePartitionChange(); GetNotifier().Signal(OT_CHANGED_THREAD_PARTITION_ID); + mCounters.mParitionIdChanges++; } else { @@ -3860,6 +3888,8 @@ otError Mle::InformPreviousParent(void) VerifyOrExit((mPreviousParentRloc != Mac::kShortAddrInvalid) && (mPreviousParentRloc != mParent.GetRloc16())); + mCounters.mParentChanges++; + VerifyOrExit((message = netif.GetIp6().NewMessage(0)) != NULL, error = OT_ERROR_NO_BUFS); SuccessOrExit(error = message->SetLength(0)); diff --git a/src/core/thread/mle.hpp b/src/core/thread/mle.hpp index 78d590f76..55c214ac8 100644 --- a/src/core/thread/mle.hpp +++ b/src/core/thread/mle.hpp @@ -1043,6 +1043,20 @@ public: */ static const char *RoleToString(otDeviceRole aRole); + /** + * This method gets the MLE counters. + * + * @returns A reference to the MLE counters. + * + */ + const otMleCounters &GetCounters(void) const { return mCounters; } + + /** + * This method resets the MLE counters. + * + */ + void ResetCounters(void) { memset(&mCounters, 0, sizeof(mCounters)); } + protected: /** * States during attach (when searching for a parent). @@ -1763,6 +1777,8 @@ private: Ip6::NetifUnicastAddress mServiceAlocs[OPENTHREAD_CONFIG_MAX_SERVER_ALOCS]; #endif + otMleCounters mCounters; + Ip6::NetifUnicastAddress mLinkLocal64; Ip6::NetifUnicastAddress mMeshLocal64; Ip6::NetifUnicastAddress mMeshLocal16;