From 1f1a826d1891fc99d14822abc0a1de257e9c6e9b Mon Sep 17 00:00:00 2001 From: Abtin Keshavarzian Date: Wed, 8 Mar 2023 16:11:10 -0800 Subject: [PATCH] [net-diag] add Net Diag Version TLV (#8834) This commit adds support for Net Diag Version TLV (TLV number 24) which returns the Thread version of device (as `uint16_t`). It also updated the `MeshDiag` to query for the Version TLV and provide it in `otMeshDiagRouterInfo`. The related CLI commands are also updated. --- include/openthread/instance.h | 2 +- include/openthread/mesh_diag.h | 10 ++++++ include/openthread/netdiag.h | 2 ++ src/cli/README.md | 35 +++++++++++---------- src/cli/cli.cpp | 16 +++++++--- src/core/thread/network_diagnostic.cpp | 9 ++++++ src/core/thread/network_diagnostic_tlvs.hpp | 7 +++++ src/core/utils/mesh_diag.cpp | 22 ++++++++++--- src/core/utils/mesh_diag.hpp | 2 ++ 9 files changed, 77 insertions(+), 28 deletions(-) diff --git a/include/openthread/instance.h b/include/openthread/instance.h index 2ee6c79f0..75d06935d 100644 --- a/include/openthread/instance.h +++ b/include/openthread/instance.h @@ -53,7 +53,7 @@ extern "C" { * @note This number versions both OpenThread platform and user APIs. * */ -#define OPENTHREAD_API_VERSION (296) +#define OPENTHREAD_API_VERSION (297) /** * @addtogroup api-instance diff --git a/include/openthread/mesh_diag.h b/include/openthread/mesh_diag.h index e4c1eb588..dd613d1fa 100644 --- a/include/openthread/mesh_diag.h +++ b/include/openthread/mesh_diag.h @@ -81,6 +81,15 @@ typedef struct otMeshDiagIp6AddrIterator otMeshDiagIp6AddrIterator; */ typedef struct otMeshDiagChildIterator otMeshDiagChildIterator; +/** + * This constant indicates that Thread Version is unknown. + * + * This is used in `otMeshDiagRouterInfo` for `mVersion` property when device does not provide its version. This + * indicates that device is likely running 1.3.0 (version value 4) or earlier. + * + */ +#define OT_MESH_DIAG_VERSION_UNKNOWN 0xffff + /** * This type represents information about a router in Thread mesh. * @@ -90,6 +99,7 @@ typedef struct otMeshDiagRouterInfo otExtAddress mExtAddress; ///< Extended MAC address. uint16_t mRloc16; ///< RLOC16. uint8_t mRouterId; ///< Router ID. + uint16_t mVersion; ///< Thread Version. `OT_MESH_DIAG_VERSION_UNKNOWN` if unknown. bool mIsThisDevice : 1; ///< Whether router is this device itself. bool mIsThisDeviceParent : 1; ///< Whether router is parent of this device (when device is a child). bool mIsLeader : 1; ///< Whether router is leader. diff --git a/include/openthread/netdiag.h b/include/openthread/netdiag.h index eb3e7b697..c4071e207 100644 --- a/include/openthread/netdiag.h +++ b/include/openthread/netdiag.h @@ -82,6 +82,7 @@ enum OT_NETWORK_DIAGNOSTIC_TLV_CHANNEL_PAGES = 17, ///< Channel Pages TLV OT_NETWORK_DIAGNOSTIC_TLV_TYPE_LIST = 18, ///< Type List TLV OT_NETWORK_DIAGNOSTIC_TLV_MAX_CHILD_TIMEOUT = 19, ///< Max Child Timeout TLV + OT_NETWORK_DIAGNOSTIC_TLV_VERSION = 24, ///< Version TLV }; typedef uint16_t otNetworkDiagIterator; ///< Used to iterate through Network Diagnostic TLV. @@ -245,6 +246,7 @@ typedef struct otNetworkDiagTlv uint8_t mBatteryLevel; uint16_t mSupplyVoltage; uint32_t mMaxChildTimeout; + uint16_t mVersion; struct { uint8_t mCount; diff --git a/src/cli/README.md b/src/cli/README.md index 58e0edb3e..f5cdf2e14 100644 --- a/src/cli/README.md +++ b/src/cli/README.md @@ -1848,6 +1848,7 @@ Output lists all discovered routers. Information per router: - Router ID - RLOC16 - Extended MAC address +- Thread Version (if known). - Whether the router is this device is itself (`me`) - Whether the router is the parent of this device when device is a child (`parent`) - Whether the router is `leader` @@ -1869,16 +1870,16 @@ Discover network topology: ```bash > meshdiag topology -id:02 rloc16:0x0800 ext-addr:8aa57d2c603fe16c - me - leader +id:02 rloc16:0x0800 ext-addr:8aa57d2c603fe16c ver:4 - me - leader 3-links:{ 46 } -id:46 rloc16:0xb800 ext-addr:fe109d277e0175cc +id:46 rloc16:0xb800 ext-addr:fe109d277e0175cc ver:4 3-links:{ 02 51 57 } -id:33 rloc16:0x8400 ext-addr:d2e511a146b9e54d +id:33 rloc16:0x8400 ext-addr:d2e511a146b9e54d ver:4 3-links:{ 51 57 } -id:51 rloc16:0xcc00 ext-addr:9aab43ababf05352 +id:51 rloc16:0xcc00 ext-addr:9aab43ababf05352 ver:4 3-links:{ 33 57 } 2-links:{ 46 } -id:57 rloc16:0xe400 ext-addr:dae9c4c0e9da55ff +id:57 rloc16:0xe400 ext-addr:dae9c4c0e9da55ff ver:4 3-links:{ 46 51 } 1-links:{ 33 } Done @@ -1888,14 +1889,14 @@ Discover network topology with router's IPv6 addresses and children: ```bash > meshdiag topology children ip6-addrs -id:62 rloc16:0xf800 ext-addr:ce349873897233a5 - me - br +id:62 rloc16:0xf800 ext-addr:ce349873897233a5 ver:4 - me - br 3-links:{ 46 } ip6-addrs: fdde:ad00:beef:0:0:ff:fe00:f800 fdde:ad00:beef:0:211d:39e9:6b2e:4ad1 fe80:0:0:0:cc34:9873:8972:33a5 children: none -id:02 rloc16:0x0800 ext-addr:8aa57d2c603fe16c - leader - br +id:02 rloc16:0x0800 ext-addr:8aa57d2c603fe16c ver:4 - leader - br 3-links:{ 46 51 } ip6-addrs: fdde:ad00:beef:0:0:ff:fe00:fc00 @@ -1905,21 +1906,21 @@ id:02 rloc16:0x0800 ext-addr:8aa57d2c603fe16c - leader - br children: rloc16:0x0803 lq:3, mode:rn rloc16:0x0804 lq:3, mode:rdn -id:33 rloc16:0x8400 ext-addr:d2e511a146b9e54d +id:33 rloc16:0x8400 ext-addr:d2e511a146b9e54d ver:4 3-links:{ 57 } ip6-addrs: fdde:ad00:beef:0:0:ff:fe00:8400 fdde:ad00:beef:0:824:a126:cf19:a9f4 fe80:0:0:0:d0e5:11a1:46b9:e54d children: none -id:51 rloc16:0xcc00 ext-addr:9aab43ababf05352 +id:51 rloc16:0xcc00 ext-addr:9aab43ababf05352 ver:4 3-links:{ 02 46 57 } ip6-addrs: fdde:ad00:beef:0:0:ff:fe00:cc00 fdde:ad00:beef:0:2986:bba3:12d0:1dd2 fe80:0:0:0:98ab:43ab:abf0:5352 children: none -id:57 rloc16:0xe400 ext-addr:dae9c4c0e9da55ff +id:57 rloc16:0xe400 ext-addr:dae9c4c0e9da55ff ver:4 3-links:{ 33 51 } ip6-addrs: fdde:ad00:beef:0:0:ff:fe00:e400 @@ -1928,7 +1929,7 @@ id:57 rloc16:0xe400 ext-addr:dae9c4c0e9da55ff children: rloc16:0xe402 lq:3, mode:rn - br rloc16:0xe403 lq:3, mode:rn -id:46 rloc16:0xb800 ext-addr:fe109d277e0175cc +id:46 rloc16:0xb800 ext-addr:fe109d277e0175cc ver:4 3-links:{ 02 51 62 } ip6-addrs: fdde:ad00:beef:0:0:ff:fe00:b800 @@ -1942,26 +1943,26 @@ Discover network topology with children: ```bash > meshdiag topology children -id:02 rloc16:0x0800 ext-addr:8aa57d2c603fe16c - parent - leader - br +id:02 rloc16:0x0800 ext-addr:8aa57d2c603fe16c ver:4 - parent - leader - br 3-links:{ 46 51 } children: rloc16:0x0803 lq:0, mode:rn rloc16:0x0804 lq:0, mode:rdn - me -id:46 rloc16:0xb800 ext-addr:fe109d277e0175cc +id:46 rloc16:0xb800 ext-addr:fe109d277e0175cc ver:4 3-links:{ 02 51 62 } children: none -id:33 rloc16:0x8400 ext-addr:d2e511a146b9e54d +id:33 rloc16:0x8400 ext-addr:d2e511a146b9e54d ver:4 3-links:{ 57 } children: none -id:51 rloc16:0xcc00 ext-addr:9aab43ababf05352 +id:51 rloc16:0xcc00 ext-addr:9aab43ababf05352 ver:4 3-links:{ 02 46 57 } children: none -id:57 rloc16:0xe400 ext-addr:dae9c4c0e9da55ff +id:57 rloc16:0xe400 ext-addr:dae9c4c0e9da55ff ver:4 3-links:{ 33 51 } children: rloc16:0xe402 lq:3, mode:rn - br rloc16:0xe403 lq:3, mode:rn -id:62 rloc16:0xf800 ext-addr:ce349873897233a5 - br +id:62 rloc16:0xf800 ext-addr:ce349873897233a5 ver:4 - br 3-links:{ 46 } children: none ``` diff --git a/src/cli/cli.cpp b/src/cli/cli.cpp index 36b40a27e..28d7ab584 100644 --- a/src/cli/cli.cpp +++ b/src/cli/cli.cpp @@ -5445,16 +5445,16 @@ template <> otError Interpreter::Process(Arg aArgs[]) * @cli meshdiag topology * @code * meshdiag topology - * id:02 rloc16:0x0800 ext-addr:8aa57d2c603fe16c - me - leader + * id:02 rloc16:0x0800 ext-addr:8aa57d2c603fe16c ver:4 - me - leader * 3-links:{ 46 } - * id:46 rloc16:0xb800 ext-addr:fe109d277e0175cc + * id:46 rloc16:0xb800 ext-addr:fe109d277e0175cc ver:4 * 3-links:{ 02 51 57 } - * id:33 rloc16:0x8400 ext-addr:d2e511a146b9e54d + * id:33 rloc16:0x8400 ext-addr:d2e511a146b9e54d ver:4 * 3-links:{ 51 57 } - * id:51 rloc16:0xcc00 ext-addr:9aab43ababf05352 + * id:51 rloc16:0xcc00 ext-addr:9aab43ababf05352 ver:4 * 3-links:{ 33 57 } * 2-links:{ 46 } - * id:57 rloc16:0xe400 ext-addr:dae9c4c0e9da55ff + * id:57 rloc16:0xe400 ext-addr:dae9c4c0e9da55ff ver:4 * 3-links:{ 46 51 } * 1-links:{ 33 } * Done @@ -5469,6 +5469,7 @@ template <> otError Interpreter::Process(Arg aArgs[]) * * Router ID * * RLOC16 * * Extended MAC address + * * Thread Version (if known) * * Whether the router is this device is itself (`me`) * * Whether the router is the parent of this device when device is a child (`parent`) * * Whether the router is `leader` @@ -5537,6 +5538,11 @@ void Interpreter::HandleMeshDiagDiscoverDone(otError aError, otMeshDiagRouterInf OutputFormat("id:%02u rloc16:0x%04x ext-addr:", aRouterInfo->mRouterId, aRouterInfo->mRloc16); OutputExtAddress(aRouterInfo->mExtAddress); + if (aRouterInfo->mVersion != OT_MESH_DIAG_VERSION_UNKNOWN) + { + OutputFormat(" ver:%u", aRouterInfo->mVersion); + } + if (aRouterInfo->mIsThisDevice) { OutputFormat(" - me"); diff --git a/src/core/thread/network_diagnostic.cpp b/src/core/thread/network_diagnostic.cpp index e5cebc895..c40c048e8 100644 --- a/src/core/thread/network_diagnostic.cpp +++ b/src/core/thread/network_diagnostic.cpp @@ -50,6 +50,7 @@ #include "thread/mle_router.hpp" #include "thread/thread_netif.hpp" #include "thread/thread_tlvs.hpp" +#include "thread/version.hpp" namespace ot { @@ -337,6 +338,10 @@ Error NetworkDiagnostic::AppendDiagTlv(uint8_t aTlvType, Message &aMessage) error = Tlv::Append(aMessage, Get().GetDeviceMode().Get()); break; + case Tlv::kVersion: + error = Tlv::Append(aMessage, kThreadVersion); + break; + case Tlv::kTimeout: VerifyOrExit(!Get().IsRxOnWhenIdle()); error = Tlv::Append(aMessage, Get().GetTimeout()); @@ -743,6 +748,10 @@ Error NetworkDiagnostic::GetNextDiagTlv(const Coap::Message &aMessage, Iterator SuccessOrExit(error = Tlv::Read(aMessage, offset, aTlvInfo.mData.mMaxChildTimeout)); break; + case Tlv::kVersion: + SuccessOrExit(error = Tlv::Read(aMessage, offset, aTlvInfo.mData.mVersion)); + break; + default: // Skip unrecognized TLVs. skipTlv = true; diff --git a/src/core/thread/network_diagnostic_tlvs.hpp b/src/core/thread/network_diagnostic_tlvs.hpp index 2dfdb6bf3..6d1fd6051 100644 --- a/src/core/thread/network_diagnostic_tlvs.hpp +++ b/src/core/thread/network_diagnostic_tlvs.hpp @@ -85,6 +85,7 @@ public: kChannelPages = OT_NETWORK_DIAGNOSTIC_TLV_CHANNEL_PAGES, kTypeList = OT_NETWORK_DIAGNOSTIC_TLV_TYPE_LIST, kMaxChildTimeout = OT_NETWORK_DIAGNOSTIC_TLV_MAX_CHILD_TIMEOUT, + kVersion = OT_NETWORK_DIAGNOSTIC_TLV_VERSION, }; /** @@ -165,6 +166,12 @@ typedef TlvInfo ChildTableTlv; */ typedef UintTlvInfo MaxChildTimeoutTlv; +/** + * This class defines Version TLV constants and types. + * + */ +typedef UintTlvInfo VersionTlv; + typedef otNetworkDiagConnectivity Connectivity; ///< Network Diagnostic Connectivity value. /** diff --git a/src/core/utils/mesh_diag.cpp b/src/core/utils/mesh_diag.cpp index 40ae5358c..29824a2da 100644 --- a/src/core/utils/mesh_diag.cpp +++ b/src/core/utils/mesh_diag.cpp @@ -94,17 +94,17 @@ Error MeshDiag::SendDiagGetTo(uint16_t aRloc16, const DiscoverConfig &aConfig) Coap::Message *message = nullptr; Tmf::MessageInfo messageInfo(GetInstance()); uint8_t tlvs[kMaxTlvsToRequest]; - uint8_t tlvsLength; + uint8_t tlvsLength = 0; message = Get().NewConfirmablePostMessage(kUriDiagnosticGetRequest); VerifyOrExit(message != nullptr, error = kErrorNoBufs); IgnoreError(message->SetPriority(Message::kPriorityLow)); - tlvs[0] = Address16Tlv::kType; - tlvs[1] = ExtMacAddressTlv::kType; - tlvs[2] = RouteTlv::kType; - tlvsLength = 3; + tlvs[tlvsLength++] = Address16Tlv::kType; + tlvs[tlvsLength++] = ExtMacAddressTlv::kType; + tlvs[tlvsLength++] = RouteTlv::kType; + tlvs[tlvsLength++] = VersionTlv::kType; if (aConfig.mDiscoverIp6Addresses) { @@ -201,6 +201,18 @@ Error MeshDiag::RouterInfo::ParseFrom(const Message &aMessage) SuccessOrExit(error = Tlv::Find(aMessage, AsCoreType(&mExtAddress))); SuccessOrExit(error = Tlv::FindTlv(aMessage, routeTlv)); + switch (error = Tlv::Find(aMessage, mVersion)) + { + case kErrorNone: + break; + case kErrorNotFound: + mVersion = kVersionUnknown; + error = kErrorNone; + break; + default: + ExitNow(); + } + mRouterId = Mle::RouterIdFromRloc16(mRloc16); mIsThisDevice = (mRloc16 == mle.GetRloc16()); mIsThisDeviceParent = mle.IsChild() && (mRloc16 == mle.GetParent().GetRloc16()); diff --git a/src/core/utils/mesh_diag.hpp b/src/core/utils/mesh_diag.hpp index 3de8e22a2..494e78462 100644 --- a/src/core/utils/mesh_diag.hpp +++ b/src/core/utils/mesh_diag.hpp @@ -66,6 +66,8 @@ namespace Utils { class MeshDiag : public InstanceLocator { public: + static constexpr uint16_t kVersionUnknown = OT_MESH_DIAG_VERSION_UNKNOWN; ///< Unknown version. + typedef otMeshDiagDiscoverConfig DiscoverConfig; ///< The discovery configuration. typedef otMeshDiagDiscoverCallback DiscoverCallback; ///< The discovery callback function pointer type.