From 529b1886096a0389d6a11afb0a0958266ac139c9 Mon Sep 17 00:00:00 2001 From: rongli Date: Sat, 8 Jul 2017 00:10:58 +0800 Subject: [PATCH] [network diagnostic] updates to consistent with spec (#1964) --- include/openthread/types.h | 8 +++- src/core/api/link_api.cpp | 2 +- src/core/thread/data_poll_manager.cpp | 25 +++++++++++- src/core/thread/data_poll_manager.hpp | 9 +++++ src/core/thread/mle_router.cpp | 30 ++++++++++++++ src/core/thread/mle_router_ftd.hpp | 12 ++++++ src/core/thread/mle_router_mtd.hpp | 4 +- src/core/thread/network_diagnostic.cpp | 18 ++++++++- src/core/thread/network_diagnostic_tlvs.hpp | 44 +++++++++++++++++++++ 9 files changed, 145 insertions(+), 7 deletions(-) diff --git a/include/openthread/types.h b/include/openthread/types.h index 7451496a2..594975df1 100644 --- a/include/openthread/types.h +++ b/include/openthread/types.h @@ -277,8 +277,12 @@ typedef enum otError #define OT_MASTER_KEY_SIZE 16 ///< Size of the Thread Master Key (bytes) -#define OT_NETWORK_DIAGNOSTIC_TYPELIST_TYPE 18 ///< Concatenated List of Type Identifiers of Other Diagnostics TLVs Used to Request or Reset Multiple Diagnostic Values -#define OT_NETWORK_DIAGNOSTIC_TYPELIST_MAX_ENTRIES 18 ///< Maximum Number of Other Network Diagnostic TLV Types +/** + * Concatenated List of Type Identifiers of Other Diagnostics TLVs Used to Request or Reset Multiple Diagnostic Values. + */ +#define OT_NETWORK_DIAGNOSTIC_TYPELIST_TYPE 18 + +#define OT_NETWORK_DIAGNOSTIC_TYPELIST_MAX_ENTRIES 19 ///< Maximum Number of Other Network Diagnostic TLV Types /** * @struct otMasterKey diff --git a/src/core/api/link_api.cpp b/src/core/api/link_api.cpp index 36e16fbd4..2ee5bbc15 100644 --- a/src/core/api/link_api.cpp +++ b/src/core/api/link_api.cpp @@ -126,7 +126,7 @@ exit: uint32_t otLinkGetPollPeriod(otInstance *aInstance) { - return aInstance->mThreadNetif.GetMeshForwarder().GetDataPollManager().GetExternalPollPeriod(); + return aInstance->mThreadNetif.GetMeshForwarder().GetDataPollManager().GetKeepAlivePollPeriod(); } void otLinkSetPollPeriod(otInstance *aInstance, uint32_t aPollPeriod) diff --git a/src/core/thread/data_poll_manager.cpp b/src/core/thread/data_poll_manager.cpp index 9151eeb12..2b0ab745b 100644 --- a/src/core/thread/data_poll_manager.cpp +++ b/src/core/thread/data_poll_manager.cpp @@ -170,6 +170,22 @@ void DataPollManager::SetExternalPollPeriod(uint32_t aPeriod) } } +uint32_t DataPollManager::GetKeepAlivePollPeriod(void) const +{ + uint32_t period = 0; + + if (mExternalPollPeriod != 0) + { + period = mExternalPollPeriod; + } + else + { + period = GetDefaultPollPeriod(); + } + + return period; +} + void DataPollManager::HandlePollSent(otError aError) { bool shouldRecalculatePollPeriod = false; @@ -377,8 +393,7 @@ uint32_t DataPollManager::CalculatePollPeriod(void) const if (period == 0) { - period = Timer::SecToMsec(GetMeshForwarder().GetNetif().GetMle().GetTimeout()) - - static_cast(kRetxPollPeriod) * kMaxPollRetxAttempts; + period = GetDefaultPollPeriod(); if (period == 0) { @@ -405,4 +420,10 @@ DataPollManager &DataPollManager::GetOwner(Context &aContext) return manager; } +uint32_t DataPollManager::GetDefaultPollPeriod(void) const +{ + return Timer::SecToMsec(GetMeshForwarder().GetNetif().GetMle().GetTimeout()) - + static_cast(kRetxPollPeriod) * kMaxPollRetxAttempts; +} + } // namespace ot diff --git a/src/core/thread/data_poll_manager.hpp b/src/core/thread/data_poll_manager.hpp index ac689279a..fbbe49ef3 100644 --- a/src/core/thread/data_poll_manager.hpp +++ b/src/core/thread/data_poll_manager.hpp @@ -185,6 +185,14 @@ public: */ void SendFastPolls(uint8_t aNumFastPolls); + /** + * This method gets the maximum data polling period in use. + * + * @returns the maximum data polling period in use. + * + */ + uint32_t GetKeepAlivePollPeriod(void) const; + private: enum // Poll period under different conditions (in milliseconds). { @@ -211,6 +219,7 @@ private: uint32_t CalculatePollPeriod(void) const; static void HandlePollTimer(Timer &aTimer); static DataPollManager &GetOwner(Context &aContext); + uint32_t GetDefaultPollPeriod(void) const; Timer mTimer; uint32_t mTimerStartTime; diff --git a/src/core/thread/mle_router.cpp b/src/core/thread/mle_router.cpp index 46c21f507..697f5a63c 100644 --- a/src/core/thread/mle_router.cpp +++ b/src/core/thread/mle_router.cpp @@ -4706,6 +4706,36 @@ MleRouter &MleRouter::GetOwner(const Context &aContext) return mle; } +otError MleRouter::GetMaxChildTimeout(uint32_t &aTimeout) const +{ + otError error = OT_ERROR_NOT_FOUND; + + VerifyOrExit(mRole == OT_DEVICE_ROLE_ROUTER || mRole == OT_DEVICE_ROLE_LEADER, error = OT_ERROR_INVALID_STATE); + + for (uint8_t i = 0; i < mMaxChildrenAllowed; i++) + { + if (mChildren[i].GetState() != Neighbor::kStateValid) + { + continue; + } + + if (mChildren[i].IsFullThreadDevice()) + { + continue; + } + + if (mChildren[i].GetTimeout() > aTimeout) + { + aTimeout = mChildren[i].GetTimeout(); + } + + error = OT_ERROR_NONE; + } + +exit: + return error; +} + } // namespace Mle } // namespace ot diff --git a/src/core/thread/mle_router_ftd.hpp b/src/core/thread/mle_router_ftd.hpp index e79b3cdb8..fca7fae3c 100644 --- a/src/core/thread/mle_router_ftd.hpp +++ b/src/core/thread/mle_router_ftd.hpp @@ -684,6 +684,18 @@ public: */ otError SetAssignParentPriority(int8_t aParentPriority); + /** + * This method gets the longest MLE Timeout TLV for all active MTD children. + * + * @param[out] aTimeout A reference to where the information is placed. + * + * @retval OT_ERROR_NONE Successfully get the max child timeout + * @retval OT_ERROR_INVALID_STATE Not an active router + * @retval OT_ERROR_NOT_FOUND NO MTD child + * + */ + otError GetMaxChildTimeout(uint32_t &aTimeout) const; + private: enum { diff --git a/src/core/thread/mle_router_mtd.hpp b/src/core/thread/mle_router_mtd.hpp index 62d90148e..6d48d8c17 100644 --- a/src/core/thread/mle_router_mtd.hpp +++ b/src/core/thread/mle_router_mtd.hpp @@ -126,9 +126,11 @@ public: otError SendChildUpdateRequest(void) { return Mle::SendChildUpdateRequest(); } #if OPENTHREAD_CONFIG_ENABLE_STEERING_DATA_SET_OOB - otError SetSteeringData(otExtAddress *) { return OT_ERROR_NOT_IMPLEMENTED; }; + otError SetSteeringData(otExtAddress *) { return OT_ERROR_NOT_IMPLEMENTED; } #endif // OPENTHREAD_CONFIG_ENABLE_STEERING_DATA_SET_OOB + otError GetMaxChildTimeout(uint32_t &) { return OT_ERROR_NOT_IMPLEMENTED; } + private: otError HandleDetachStart(void) { return OT_ERROR_NONE; } otError HandleChildStart(AttachMode) { return OT_ERROR_NONE; } diff --git a/src/core/thread/network_diagnostic.cpp b/src/core/thread/network_diagnostic.cpp index 42f91408a..a17dfdaf7 100644 --- a/src/core/thread/network_diagnostic.cpp +++ b/src/core/thread/network_diagnostic.cpp @@ -316,7 +316,8 @@ otError NetworkDiagnostic::FillRequestedTlvs(Message &aRequest, Message &aRespon { TimeoutTlv tlv; tlv.Init(); - tlv.SetTimeout(netif.GetMle().GetTimeout()); + tlv.SetTimeout( + Timer::MsecToSec(netif.GetMeshForwarder().GetDataPollManager().GetKeepAlivePollPeriod())); SuccessOrExit(error = aResponse.Append(&tlv, sizeof(tlv))); } @@ -411,6 +412,21 @@ otError NetworkDiagnostic::FillRequestedTlvs(Message &aRequest, Message &aRespon break; } + case NetworkDiagnosticTlv::kMaxChildTimeout: + { + uint32_t maxTimeout = 0; + + if (netif.GetMle().GetMaxChildTimeout(maxTimeout) == OT_ERROR_NONE) + { + MaxChildTimeoutTlv tlv; + tlv.Init(); + tlv.SetTimeout(maxTimeout); + SuccessOrExit(error = aResponse.Append(&tlv, sizeof(tlv))); + } + + break; + } + default: ExitNow(error = OT_ERROR_DROP); } diff --git a/src/core/thread/network_diagnostic_tlvs.hpp b/src/core/thread/network_diagnostic_tlvs.hpp index d3e7d297e..8da079d69 100644 --- a/src/core/thread/network_diagnostic_tlvs.hpp +++ b/src/core/thread/network_diagnostic_tlvs.hpp @@ -97,6 +97,7 @@ public: kChildTable = 16, ///< Child Table TLV kChannelPages = 17, ///< Channel Pages TLV kTypeList = 18, ///< Type List TLV + kMaxChildTimeout = 19, ///< Max Child Timeout TLV kInvalid = 255, }; @@ -1360,6 +1361,49 @@ public: */ } OT_TOOL_PACKED_END; +/** + * This class implements Max Child Timeout TLV generation and parsing. + * + */ +OT_TOOL_PACKED_BEGIN +class MaxChildTimeoutTlv: public NetworkDiagnosticTlv +{ +public: + /** + * This method initializes the TLV. + * + */ + void Init(void) { SetType(kMaxChildTimeout); SetLength(sizeof(*this) - sizeof(NetworkDiagnosticTlv)); } + + /** + * This method indicates whether or not the TLV appears to be well-formed. + * + * @retval TRUE If the TLV appears to be well-formed. + * @retval FALSE If the TLV does not appear to be well-formed. + * + */ + bool IsValid(void) const { return GetLength() == sizeof(*this) - sizeof(NetworkDiagnosticTlv); } + + /** + * This method returns the Timeout value. + * + * @returns The Timeout value. + * + */ + uint32_t GetTimeout(void) const { return HostSwap32(mTimeout); } + + /** + * This method sets the Timeout value. + * + * @param[in] aTimeout The Timeout value. + * + */ + void SetTimeout(uint32_t aTimeout) { mTimeout = HostSwap32(aTimeout); } + +private: + uint32_t mTimeout; +} OT_TOOL_PACKED_END; + /** * @} *