diff --git a/include/openthread/border_routing.h b/include/openthread/border_routing.h index c0589234e..464cf0039 100644 --- a/include/openthread/border_routing.h +++ b/include/openthread/border_routing.h @@ -191,10 +191,10 @@ typedef enum */ typedef enum { - OT_BORDER_ROUTING_STATE_UNINITIALIZED, ///< Routing Manager is uninitialized. - OT_BORDER_ROUTING_STATE_DISABLED, ///< Routing Manager is initialized but disabled. - OT_BORDER_ROUTING_STATE_STOPPED, ///< Routing Manager in initialized and enabled but currently stopped. - OT_BORDER_ROUTING_STATE_RUNNING, ///< Routing Manager is initialized, enabled, and running. + OT_BORDER_ROUTING_STATE_UNINITIALIZED = 0, ///< Routing Manager is uninitialized. + OT_BORDER_ROUTING_STATE_DISABLED = 1, ///< Routing Manager is initialized but disabled. + OT_BORDER_ROUTING_STATE_STOPPED = 2, ///< Routing Manager in initialized and enabled but currently stopped. + OT_BORDER_ROUTING_STATE_RUNNING = 3, ///< Routing Manager is initialized, enabled, and running. } otBorderRoutingState; /** diff --git a/include/openthread/instance.h b/include/openthread/instance.h index 18b7e2f81..d53c2015c 100644 --- a/include/openthread/instance.h +++ b/include/openthread/instance.h @@ -52,7 +52,7 @@ extern "C" { * * @note This number versions both OpenThread platform and user APIs. */ -#define OPENTHREAD_API_VERSION (540) +#define OPENTHREAD_API_VERSION (541) /** * @addtogroup api-instance diff --git a/include/openthread/netdiag.h b/include/openthread/netdiag.h index 201fdca3e..9770b70fd 100644 --- a/include/openthread/netdiag.h +++ b/include/openthread/netdiag.h @@ -38,6 +38,7 @@ #include #include +#include #include #include #include @@ -87,6 +88,12 @@ extern "C" { #define OT_NETWORK_DIAGNOSTIC_TLV_VENDOR_APP_URL 35 ///< Vendor App URL TLV #define OT_NETWORK_DIAGNOSTIC_TLV_NON_PREFERRED_CHANNELS 36 ///< Non-Preferred Channels Mask TLV #define OT_NETWORK_DIAGNOSTIC_TLV_ENHANCED_ROUTE 37 ///< Enhanced Route TLV +#define OT_NETWORK_DIAGNOSTIC_TLV_BR_STATE 38 ///< Border Router State TLV +#define OT_NETWORK_DIAGNOSTIC_TLV_BR_IF_ADDRS 39 ///< Border Router Infra Interface Addresses TLV +#define OT_NETWORK_DIAGNOSTIC_TLV_BR_LOCAL_OMR_PREFIX 40 ///< Border Router Local OMR Prefix TLV +#define OT_NETWORK_DIAGNOSTIC_TLV_BR_DHCP6_PD_OMR_PREFIX 41 ///< Border Router DHCPv6-PD OMR Prefix TLV +#define OT_NETWORK_DIAGNOSTIC_TLV_BR_LOCAL_OL_PREFIX 42 ///< Border Router Local On-link Prefix TLV +#define OT_NETWORK_DIAGNOSTIC_TLV_BR_FAVORED_OL_PREFIX 43 ///< Border Router Favored On-link Prefix TLV #define OT_NETWORK_DIAGNOSTIC_MAX_VENDOR_NAME_TLV_LENGTH 32 ///< Max length of Vendor Name TLV. #define OT_NETWORK_DIAGNOSTIC_MAX_VENDOR_MODEL_TLV_LENGTH 32 ///< Max length of Vendor Model TLV. @@ -261,6 +268,11 @@ typedef struct otNetworkDiagChildTable otNetworkDiagChildEntry mTable[OT_NETWORK_BASE_TLV_MAX_LENGTH / sizeof(otNetworkDiagChildEntry)]; ///< Child table. } otNetworkDiagChildTable; +/** + * Represents a Border Router State TLV value. + */ +typedef otBorderRoutingState otNetworkDiagBrState; + /** * Represents a Network Diagnostic TLV. */ @@ -295,6 +307,9 @@ typedef struct otNetworkDiagTlv otChannelMask mNonPreferredChannels; otNetworkDiagData mChannelPages; otNetworkDiagChildTable mChildTable; + otNetworkDiagBrState mBrState; + otNetworkDiagIp6AddrList mBrIfAddrList; + otIp6NetworkPrefix mBrPrefix; // This field is shared for various BR prefix TLV (OMR, on-link). } mData; } otNetworkDiagTlv; diff --git a/src/cli/cli.cpp b/src/cli/cli.cpp index c01994b4c..e408190d2 100644 --- a/src/cli/cli.cpp +++ b/src/cli/cli.cpp @@ -7864,6 +7864,13 @@ template <> otError Interpreter::Process(Arg aArgs[]) * - `34`: MLE Counters TLV * - `35`: Vendor App URL TLV * - `37`: Enhanced Route TLV + * - `38`: Border Router State TLV + * - `39`: Border Router Infra Interface Addresses TLV + * - `40`: Border Router Local OMR Prefix TLV + * - `41`: Border Router DHCPv6-PD OMR Prefix TLV + * - `42`: Border Router Local On-link Prefix TLV + * - `43`: Border Router Favored On-link Prefix TLV + * * @par * Sends a network diagnostic request to retrieve specified Type Length Values (TLVs) * for the specified addresses(es). @@ -7986,11 +7993,7 @@ void Interpreter::HandleDiagnosticGetResponse(otError aError, break; case OT_NETWORK_DIAGNOSTIC_TLV_IP6_ADDR_LIST: OutputLine("IP6 Address List:"); - for (uint16_t i = 0; i < diagTlv.mData.mIp6AddrList.mCount; ++i) - { - OutputFormat(kIndentSize, "- "); - OutputIp6AddressLine(diagTlv.mData.mIp6AddrList.mList[i]); - } + OutputIp6AddrList(kIndentSize, diagTlv.mData.mIp6AddrList); break; case OT_NETWORK_DIAGNOSTIC_TLV_MAC_COUNTERS: OutputLine("MAC Counters:"); @@ -8044,6 +8047,29 @@ void Interpreter::HandleDiagnosticGetResponse(otError aError, case OT_NETWORK_DIAGNOSTIC_TLV_NON_PREFERRED_CHANNELS: OutputLine("Non-preferred Channels Mask: 0x%lx", ToUlong(diagTlv.mData.mNonPreferredChannels)); break; + case OT_NETWORK_DIAGNOSTIC_TLV_BR_STATE: + OutputLine("BR State: %s", BorderRoutingStateToString(diagTlv.mData.mBrState)); + break; + case OT_NETWORK_DIAGNOSTIC_TLV_BR_IF_ADDRS: + OutputLine("BR Infra-if IP6 Address List:"); + OutputIp6AddrList(kIndentSize, diagTlv.mData.mBrIfAddrList); + break; + case OT_NETWORK_DIAGNOSTIC_TLV_BR_LOCAL_OMR_PREFIX: + OutputFormat("BR Local OMR Prefix: "); + OutputIp6PrefixLine(diagTlv.mData.mBrPrefix); + break; + case OT_NETWORK_DIAGNOSTIC_TLV_BR_DHCP6_PD_OMR_PREFIX: + OutputFormat("BR DHCPv6-PD OMR Prefix: "); + OutputIp6PrefixLine(diagTlv.mData.mBrPrefix); + break; + case OT_NETWORK_DIAGNOSTIC_TLV_BR_LOCAL_OL_PREFIX: + OutputFormat("BR Local On-link Prefix: "); + OutputIp6PrefixLine(diagTlv.mData.mBrPrefix); + break; + case OT_NETWORK_DIAGNOSTIC_TLV_BR_FAVORED_OL_PREFIX: + OutputFormat("BR Favored On-link Prefix: "); + OutputIp6PrefixLine(diagTlv.mData.mBrPrefix); + break; default: break; } @@ -8134,6 +8160,15 @@ void Interpreter::OutputLeaderData(uint8_t aIndentSize, const otLeaderData &aLea OutputLine(aIndentSize, "LeaderRouterId: 0x%02x", aLeaderData.mLeaderRouterId); } +void Interpreter::OutputIp6AddrList(uint8_t aIndentSize, const otNetworkDiagIp6AddrList &aIp6Addrs) +{ + for (uint8_t i = 0; i < aIp6Addrs.mCount; ++i) + { + OutputFormat(aIndentSize, "- "); + OutputIp6AddressLine(aIp6Addrs.mList[i]); + } +} + void Interpreter::OutputNetworkDiagMacCounters(uint8_t aIndentSize, const otNetworkDiagMacCounters &aMacCounters) { struct CounterName diff --git a/src/cli/cli.hpp b/src/cli/cli.hpp index 9b7c2de0d..dfa4fef37 100644 --- a/src/cli/cli.hpp +++ b/src/cli/cli.hpp @@ -264,6 +264,7 @@ private: void OutputRouteData(uint8_t aIndentSize, const otNetworkDiagRouteData &aRouteData); void OutputEnhRoute(uint8_t aIndentSize, const otNetworkDiagEnhRoute &aEnhRoute); void OutputLeaderData(uint8_t aIndentSize, const otLeaderData &aLeaderData); + void OutputIp6AddrList(uint8_t aIndentSize, const otNetworkDiagIp6AddrList &aIp6Addrs); void OutputNetworkDiagMacCounters(uint8_t aIndentSize, const otNetworkDiagMacCounters &aMacCounters); void OutputNetworkDiagMleCounters(uint8_t aIndentSize, const otNetworkDiagMleCounters &aMleCounters); void OutputChildTableEntry(uint8_t aIndentSize, const otNetworkDiagChildEntry &aChildEntry); diff --git a/src/cli/cli_br.cpp b/src/cli/cli_br.cpp index b0ef862e0..d980c3290 100644 --- a/src/cli/cli_br.cpp +++ b/src/cli/cli_br.cpp @@ -145,23 +145,10 @@ exit: */ template <> otError Br::Process(Arg aArgs[]) { - static const char *const kStateStrings[] = { - - "uninitialized", // (0) OT_BORDER_ROUTING_STATE_UNINITIALIZED - "disabled", // (1) OT_BORDER_ROUTING_STATE_DISABLED - "stopped", // (2) OT_BORDER_ROUTING_STATE_STOPPED - "running", // (3) OT_BORDER_ROUTING_STATE_RUNNING - }; - otError error = OT_ERROR_NONE; - static_assert(0 == OT_BORDER_ROUTING_STATE_UNINITIALIZED, "STATE_UNINITIALIZED value is incorrect"); - static_assert(1 == OT_BORDER_ROUTING_STATE_DISABLED, "STATE_DISABLED value is incorrect"); - static_assert(2 == OT_BORDER_ROUTING_STATE_STOPPED, "STATE_STOPPED value is incorrect"); - static_assert(3 == OT_BORDER_ROUTING_STATE_RUNNING, "STATE_RUNNING value is incorrect"); - VerifyOrExit(aArgs[0].IsEmpty(), error = OT_ERROR_INVALID_ARGS); - OutputLine("%s", Stringify(otBorderRoutingGetState(GetInstancePtr()), kStateStrings)); + OutputLine("%s", BorderRoutingStateToString(otBorderRoutingGetState(GetInstancePtr()))); exit: return error; diff --git a/src/cli/cli_utils.cpp b/src/cli/cli_utils.cpp index bed0198bd..33182dffb 100644 --- a/src/cli/cli_utils.cpp +++ b/src/cli/cli_utils.cpp @@ -810,5 +810,22 @@ const char *Utils::AddressOriginToString(uint8_t aOrigin) return Stringify(aOrigin, kOriginStrings); } +const char *Utils::BorderRoutingStateToString(otBorderRoutingState aState) +{ + static const char *const kStateStrings[] = { + "uninitialized", // (0) OT_BORDER_ROUTING_STATE_UNINITIALIZED + "disabled", // (1) OT_BORDER_ROUTING_STATE_DISABLED + "stopped", // (2) OT_BORDER_ROUTING_STATE_STOPPED + "running", // (3) OT_BORDER_ROUTING_STATE_RUNNING + }; + + static_assert(0 == OT_BORDER_ROUTING_STATE_UNINITIALIZED, "STATE_UNINITIALIZED value is incorrect"); + static_assert(1 == OT_BORDER_ROUTING_STATE_DISABLED, "STATE_DISABLED value is incorrect"); + static_assert(2 == OT_BORDER_ROUTING_STATE_STOPPED, "STATE_STOPPED value is incorrect"); + static_assert(3 == OT_BORDER_ROUTING_STATE_RUNNING, "STATE_RUNNING value is incorrect"); + + return Stringify(aState, kStateStrings); +} + } // namespace Cli } // namespace ot diff --git a/src/cli/cli_utils.hpp b/src/cli/cli_utils.hpp index 7496de8a5..d4cf96189 100644 --- a/src/cli/cli_utils.hpp +++ b/src/cli/cli_utils.hpp @@ -718,6 +718,15 @@ public: */ static const char *AddressOriginToString(uint8_t aOrigin); + /** + * Converts a given `otBorderRoutingState` value (`OT_BORDER_ROUTING_STATE_*`) to human-readable string. + * + * @param[in] aState The BR state to convert. + * + * @returns A human-readable string representation of @p aState. + */ + static const char *BorderRoutingStateToString(otBorderRoutingState aState); + protected: void OutputFormatV(const char *aFormat, va_list aArguments); diff --git a/src/core/net/ip6_address.cpp b/src/core/net/ip6_address.cpp index 3e1ff3981..638314e5e 100644 --- a/src/core/net/ip6_address.cpp +++ b/src/core/net/ip6_address.cpp @@ -48,6 +48,17 @@ Error NetworkPrefix::GenerateRandomUla(void) return Random::Crypto::FillBuffer(&m8[1], kSize - 1); } +Error NetworkPrefix::SetFrom(const Prefix &aPrefix) +{ + Error error = kErrorNone; + + VerifyOrExit(aPrefix.GetLength() == kLength, error = kErrorInvalidArgs); + memcpy(m8, aPrefix.GetBytes(), kSize); + +exit: + return error; +} + //--------------------------------------------------------------------------------------------------------------------- // Prefix methods diff --git a/src/core/net/ip6_address.hpp b/src/core/net/ip6_address.hpp index 422182be8..f0f9e1877 100644 --- a/src/core/net/ip6_address.hpp +++ b/src/core/net/ip6_address.hpp @@ -61,6 +61,8 @@ namespace Ip6 { * @{ */ +class Prefix; + /** * Represents the Network Prefix of an IPv6 address (most significant 64 bits of the address). */ @@ -80,6 +82,16 @@ public: */ Error GenerateRandomUla(void); + /** + * Sets the Network Prefix from a given `Prefix`. + * + * @param[in] aPrefix The prefix to use to set the Network Prefix. + * + * @retval kErrorNone Successfully set the Network Prefix from @p aPrefix. + * @retval kErrorInvalidArgs The @p aPrefix length is not valid (must be `kLength`). + */ + Error SetFrom(const Prefix &aPrefix); + } OT_TOOL_PACKED_END; /** diff --git a/src/core/thread/network_diagnostic.cpp b/src/core/thread/network_diagnostic.cpp index 281a178a6..5b8792810 100644 --- a/src/core/thread/network_diagnostic.cpp +++ b/src/core/thread/network_diagnostic.cpp @@ -327,6 +327,82 @@ Error Server::AppendMacCounters(Message &aMessage) return tlv.AppendTo(aMessage); } +#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE + +Error Server::AppendBorderRouterIfAddrs(Message &aMessage) +{ + Error error; + Tlv tlv; + uint16_t offset; + uint16_t length = 0; + BorderRouter::PrefixTableIterator iterator; + BorderRouter::IfAddrEntry ifAddr; + + tlv.SetType(Tlv::kBrIfAddrs); + + offset = aMessage.GetLength(); + SuccessOrExit(error = aMessage.Append(tlv)); + + Get().InitPrefixTableIterator(iterator); + + while (Get().GetNextIfAddrEntry(iterator, ifAddr) == kErrorNone) + { + if (length + sizeof(Ip6::Address) > Tlv::kBaseTlvMaxLength) + { + break; + } + + SuccessOrExit(error = aMessage.Append(ifAddr.mAddress)); + length += sizeof(Ip6::Address); + } + + tlv.SetLength(ClampToUint8(length)); + aMessage.Write(offset, tlv); + +exit: + return error; +} + +Error Server::AppendBrPrefixTlv(uint8_t aTlvType, Message &aMessage) +{ + Ip6::Prefix prefix; + Ip6::NetworkPrefix netPrefix; + + netPrefix.Clear(); + + switch (aTlvType) + { + case Tlv::kBrLocalOmrPrefix: + SuccessOrExit(Get().GetOmrPrefix(prefix)); + break; + case Tlv::kBrLocalOnlinkPrefix: + SuccessOrExit(Get().GetOnLinkPrefix(prefix)); + break; + case Tlv::kBrFavoredOnLinkPrefix: + SuccessOrExit(Get().GetFavoredOnLinkPrefix(prefix)); + break; +#if OPENTHREAD_CONFIG_BORDER_ROUTING_DHCP6_PD_ENABLE + case Tlv::kBrDhcp6PdOmrPrefix: + { + BorderRouter::Dhcp6PdPrefix pdPrefix; + + SuccessOrExit(Get().GetDhcp6PdOmrPrefix(pdPrefix)); + prefix = AsCoreType(&pdPrefix.mPrefix); + break; + } +#endif + default: + ExitNow(); + } + + IgnoreError(netPrefix.SetFrom(prefix)); + +exit: + return Tlv::AppendTlv(aMessage, aTlvType, &netPrefix, sizeof(netPrefix)); +} + +#endif // OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE + Error Server::AppendRequestedTlvs(const Message &aRequest, Message &aResponse) { Error error; @@ -566,6 +642,25 @@ Error Server::AppendDiagTlv(uint8_t aTlvType, Message &aMessage) #endif // OPENTHREAD_FTD +#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE + + case Tlv::kBrState: + error = Tlv::Append(aMessage, Get().GetState()); + break; + + case Tlv::kBrIfAddrs: + error = AppendBorderRouterIfAddrs(aMessage); + break; + + case Tlv::kBrLocalOmrPrefix: + case Tlv::kBrDhcp6PdOmrPrefix: + case Tlv::kBrLocalOnlinkPrefix: + case Tlv::kBrFavoredOnLinkPrefix: + error = AppendBrPrefixTlv(aTlvType, aMessage); + break; + +#endif + default: break; } @@ -1232,7 +1327,7 @@ exit: return error; } -static inline void ParseMacCounters(const MacCountersTlv &aMacCountersTlv, otNetworkDiagMacCounters &aMacCounters) +void Client::ParseMacCounters(const MacCountersTlv &aMacCountersTlv, otNetworkDiagMacCounters &aMacCounters) { aMacCounters.mIfInUnknownProtos = aMacCountersTlv.GetIfInUnknownProtos(); aMacCounters.mIfInErrors = aMacCountersTlv.GetIfInErrors(); @@ -1245,6 +1340,19 @@ static inline void ParseMacCounters(const MacCountersTlv &aMacCountersTlv, otNet aMacCounters.mIfOutDiscards = aMacCountersTlv.GetIfOutDiscards(); } +void Client::ParseIp6AddrList(Ip6AddrList &aIp6Addrs, const Message &aMessage, OffsetRange aOffsetRange) +{ + aIp6Addrs.mCount = 0; + + while (aOffsetRange.Contains(sizeof(Ip6::Address)) && (aIp6Addrs.mCount < GetArrayLength(aIp6Addrs.mList))) + { + IgnoreError(aMessage.Read(aOffsetRange, aIp6Addrs.mList[aIp6Addrs.mCount])); + aOffsetRange.AdvanceOffset(sizeof(Ip6::Address)); + + aIp6Addrs.mCount++; + } +} + Error Client::GetNextDiagTlv(const Coap::Message &aMessage, Iterator &aIterator, TlvInfo &aTlvInfo) { Error error; @@ -1346,29 +1454,8 @@ Error Client::GetNextDiagTlv(const Coap::Message &aMessage, Iterator &aIterator, break; case Tlv::kIp6AddressList: - { - uint16_t addrListLength = GetArrayLength(aTlvInfo.mData.mIp6AddrList.mList); - Ip6::Address *addrEntry = AsCoreTypePtr(&aTlvInfo.mData.mIp6AddrList.mList[0]); - uint8_t &addrCount = aTlvInfo.mData.mIp6AddrList.mCount; - - VerifyOrExit((valueOffsetRange.GetLength() % Ip6::Address::kSize) == 0, error = kErrorParse); - - // `TlvInfo` has a fixed array for IPv6 addresses. If there - // are more addresses in the message, we read and return as - // many as can fit in array and ignore the rest. - - addrCount = 0; - - while (!valueOffsetRange.IsEmpty() && (addrCount < addrListLength)) - { - SuccessOrExit(error = aMessage.Read(valueOffsetRange, *addrEntry)); - addrCount++; - addrEntry++; - valueOffsetRange.AdvanceOffset(Ip6::Address::kSize); - } - + ParseIp6AddrList(aTlvInfo.mData.mIp6AddrList, aMessage, valueOffsetRange); break; - } case Tlv::kMacCounters: { @@ -1476,6 +1563,26 @@ Error Client::GetNextDiagTlv(const Coap::Message &aMessage, Iterator &aIterator, aTlvInfo.mData.mNonPreferredChannels)); break; + case Tlv::kBrState: + { + uint8_t state; + + SuccessOrExit(error = Tlv::Read(aMessage, offset, state)); + aTlvInfo.mData.mBrState = static_cast(state); + break; + } + + case Tlv::kBrIfAddrs: + ParseIp6AddrList(aTlvInfo.mData.mBrIfAddrList, aMessage, valueOffsetRange); + break; + + case Tlv::kBrLocalOmrPrefix: + case Tlv::kBrLocalOnlinkPrefix: + case Tlv::kBrFavoredOnLinkPrefix: + case Tlv::kBrDhcp6PdOmrPrefix: + SuccessOrExit(error = aMessage.Read(valueOffsetRange, aTlvInfo.mData.mBrPrefix)); + break; + default: // Skip unrecognized TLVs. skipTlv = true; diff --git a/src/core/thread/network_diagnostic.hpp b/src/core/thread/network_diagnostic.hpp index eff7953a1..1efcd981d 100644 --- a/src/core/thread/network_diagnostic.hpp +++ b/src/core/thread/network_diagnostic.hpp @@ -265,6 +265,10 @@ private: const Ip6::MessageInfo *aMessageInfo, Error aResult); #endif +#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE + Error AppendBorderRouterIfAddrs(Message &aMessage); + Error AppendBrPrefixTlv(uint8_t aTlvType, Message &aMessage); +#endif template void HandleTmf(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo); @@ -357,6 +361,9 @@ public: uint16_t GetLastQueryId(void) const { return mQueryId; } private: + typedef otNetworkDiagIp6AddrList Ip6AddrList; + typedef otNetworkDiagMacCounters MacCounters; + Error SendCommand(Uri aUri, Message::Priority aPriority, const Ip6::Address &aDestination, @@ -373,6 +380,9 @@ private: template void HandleTmf(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo); + static void ParseIp6AddrList(Ip6AddrList &aIp6Addrs, const Message &aMessage, OffsetRange aOffsetRange); + static void ParseMacCounters(const MacCountersTlv &aMacCountersTlv, MacCounters &aMacCounters); + #if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_INFO) static const char *UriToString(Uri aUri); #endif diff --git a/src/core/thread/network_diagnostic_tlvs.hpp b/src/core/thread/network_diagnostic_tlvs.hpp index a747987bc..d506d2d79 100644 --- a/src/core/thread/network_diagnostic_tlvs.hpp +++ b/src/core/thread/network_diagnostic_tlvs.hpp @@ -66,37 +66,43 @@ public: */ enum Type : uint8_t { - kExtMacAddress = OT_NETWORK_DIAGNOSTIC_TLV_EXT_ADDRESS, - kAddress16 = OT_NETWORK_DIAGNOSTIC_TLV_SHORT_ADDRESS, - kMode = OT_NETWORK_DIAGNOSTIC_TLV_MODE, - kTimeout = OT_NETWORK_DIAGNOSTIC_TLV_TIMEOUT, - kConnectivity = OT_NETWORK_DIAGNOSTIC_TLV_CONNECTIVITY, - kRoute = OT_NETWORK_DIAGNOSTIC_TLV_ROUTE, - kLeaderData = OT_NETWORK_DIAGNOSTIC_TLV_LEADER_DATA, - kNetworkData = OT_NETWORK_DIAGNOSTIC_TLV_NETWORK_DATA, - kIp6AddressList = OT_NETWORK_DIAGNOSTIC_TLV_IP6_ADDR_LIST, - kMacCounters = OT_NETWORK_DIAGNOSTIC_TLV_MAC_COUNTERS, - kBatteryLevel = OT_NETWORK_DIAGNOSTIC_TLV_BATTERY_LEVEL, - kSupplyVoltage = OT_NETWORK_DIAGNOSTIC_TLV_SUPPLY_VOLTAGE, - kChildTable = OT_NETWORK_DIAGNOSTIC_TLV_CHILD_TABLE, - kChannelPages = OT_NETWORK_DIAGNOSTIC_TLV_CHANNEL_PAGES, - kTypeList = OT_NETWORK_DIAGNOSTIC_TLV_TYPE_LIST, - kMaxChildTimeout = OT_NETWORK_DIAGNOSTIC_TLV_MAX_CHILD_TIMEOUT, - kEui64 = OT_NETWORK_DIAGNOSTIC_TLV_EUI64, - kVersion = OT_NETWORK_DIAGNOSTIC_TLV_VERSION, - kVendorName = OT_NETWORK_DIAGNOSTIC_TLV_VENDOR_NAME, - kVendorModel = OT_NETWORK_DIAGNOSTIC_TLV_VENDOR_MODEL, - kVendorSwVersion = OT_NETWORK_DIAGNOSTIC_TLV_VENDOR_SW_VERSION, - kThreadStackVersion = OT_NETWORK_DIAGNOSTIC_TLV_THREAD_STACK_VERSION, - kChild = OT_NETWORK_DIAGNOSTIC_TLV_CHILD, - kChildIp6AddressList = OT_NETWORK_DIAGNOSTIC_TLV_CHILD_IP6_ADDR_LIST, - kRouterNeighbor = OT_NETWORK_DIAGNOSTIC_TLV_ROUTER_NEIGHBOR, - kAnswer = OT_NETWORK_DIAGNOSTIC_TLV_ANSWER, - kQueryId = OT_NETWORK_DIAGNOSTIC_TLV_QUERY_ID, - kMleCounters = OT_NETWORK_DIAGNOSTIC_TLV_MLE_COUNTERS, - kVendorAppUrl = OT_NETWORK_DIAGNOSTIC_TLV_VENDOR_APP_URL, - kNonPreferredChannels = OT_NETWORK_DIAGNOSTIC_TLV_NON_PREFERRED_CHANNELS, - kEnhancedRoute = OT_NETWORK_DIAGNOSTIC_TLV_ENHANCED_ROUTE, + kExtMacAddress = OT_NETWORK_DIAGNOSTIC_TLV_EXT_ADDRESS, + kAddress16 = OT_NETWORK_DIAGNOSTIC_TLV_SHORT_ADDRESS, + kMode = OT_NETWORK_DIAGNOSTIC_TLV_MODE, + kTimeout = OT_NETWORK_DIAGNOSTIC_TLV_TIMEOUT, + kConnectivity = OT_NETWORK_DIAGNOSTIC_TLV_CONNECTIVITY, + kRoute = OT_NETWORK_DIAGNOSTIC_TLV_ROUTE, + kLeaderData = OT_NETWORK_DIAGNOSTIC_TLV_LEADER_DATA, + kNetworkData = OT_NETWORK_DIAGNOSTIC_TLV_NETWORK_DATA, + kIp6AddressList = OT_NETWORK_DIAGNOSTIC_TLV_IP6_ADDR_LIST, + kMacCounters = OT_NETWORK_DIAGNOSTIC_TLV_MAC_COUNTERS, + kBatteryLevel = OT_NETWORK_DIAGNOSTIC_TLV_BATTERY_LEVEL, + kSupplyVoltage = OT_NETWORK_DIAGNOSTIC_TLV_SUPPLY_VOLTAGE, + kChildTable = OT_NETWORK_DIAGNOSTIC_TLV_CHILD_TABLE, + kChannelPages = OT_NETWORK_DIAGNOSTIC_TLV_CHANNEL_PAGES, + kTypeList = OT_NETWORK_DIAGNOSTIC_TLV_TYPE_LIST, + kMaxChildTimeout = OT_NETWORK_DIAGNOSTIC_TLV_MAX_CHILD_TIMEOUT, + kEui64 = OT_NETWORK_DIAGNOSTIC_TLV_EUI64, + kVersion = OT_NETWORK_DIAGNOSTIC_TLV_VERSION, + kVendorName = OT_NETWORK_DIAGNOSTIC_TLV_VENDOR_NAME, + kVendorModel = OT_NETWORK_DIAGNOSTIC_TLV_VENDOR_MODEL, + kVendorSwVersion = OT_NETWORK_DIAGNOSTIC_TLV_VENDOR_SW_VERSION, + kThreadStackVersion = OT_NETWORK_DIAGNOSTIC_TLV_THREAD_STACK_VERSION, + kChild = OT_NETWORK_DIAGNOSTIC_TLV_CHILD, + kChildIp6AddressList = OT_NETWORK_DIAGNOSTIC_TLV_CHILD_IP6_ADDR_LIST, + kRouterNeighbor = OT_NETWORK_DIAGNOSTIC_TLV_ROUTER_NEIGHBOR, + kAnswer = OT_NETWORK_DIAGNOSTIC_TLV_ANSWER, + kQueryId = OT_NETWORK_DIAGNOSTIC_TLV_QUERY_ID, + kMleCounters = OT_NETWORK_DIAGNOSTIC_TLV_MLE_COUNTERS, + kVendorAppUrl = OT_NETWORK_DIAGNOSTIC_TLV_VENDOR_APP_URL, + kNonPreferredChannels = OT_NETWORK_DIAGNOSTIC_TLV_NON_PREFERRED_CHANNELS, + kEnhancedRoute = OT_NETWORK_DIAGNOSTIC_TLV_ENHANCED_ROUTE, + kBrState = OT_NETWORK_DIAGNOSTIC_TLV_BR_STATE, + kBrIfAddrs = OT_NETWORK_DIAGNOSTIC_TLV_BR_IF_ADDRS, + kBrLocalOmrPrefix = OT_NETWORK_DIAGNOSTIC_TLV_BR_LOCAL_OMR_PREFIX, + kBrDhcp6PdOmrPrefix = OT_NETWORK_DIAGNOSTIC_TLV_BR_DHCP6_PD_OMR_PREFIX, + kBrLocalOnlinkPrefix = OT_NETWORK_DIAGNOSTIC_TLV_BR_LOCAL_OL_PREFIX, + kBrFavoredOnLinkPrefix = OT_NETWORK_DIAGNOSTIC_TLV_BR_FAVORED_OL_PREFIX, }; /** @@ -235,6 +241,41 @@ typedef TlvInfo ChildIp6AddressListTlv; */ typedef UintTlvInfo QueryIdTlv; +/** + * Defines BR State TLV constants and types. + */ +typedef UintTlvInfo BrStateTlv; + +/** + * Represents a BR State TLV value. + */ +typedef otNetworkDiagBrState BrState; + +/** + * Defines BR Infra-if Address List TLV constants and types. + */ +typedef TlvInfo BrIfAddrsTlv; + +/** + * Defines BR Local OMR Prefix TLV constants and types. + */ +typedef SimpleTlvInfo BrLocalOmrPrefixTlv; + +/** + * Defines BR DHCPv6-PD Prefix TLV constants and types. + */ +typedef SimpleTlvInfo BrDhcp6PdOmrPrefixTlv; + +/** + * Defines BR Local On-link Prefix TLV constants and types. + */ +typedef SimpleTlvInfo BrLocalOnlinkPrefixTlv; + +/** + * Defines BR Favored On-link Prefix TLV constants and types. + */ +typedef SimpleTlvInfo BrFavoredOnLinkPrefixTlv; + typedef otNetworkDiagConnectivity Connectivity; ///< Network Diagnostic Connectivity value. /** diff --git a/tests/toranj/cli/test-503-peer-tbr-discovery.py b/tests/toranj/cli/test-503-peer-tbr-discovery.py index 2f2b668f5..dd2d974da 100755 --- a/tests/toranj/cli/test-503-peer-tbr-discovery.py +++ b/tests/toranj/cli/test-503-peer-tbr-discovery.py @@ -71,6 +71,13 @@ verify(br3.get_state() == 'router') # ----------------------------------------------------------------------------------------------------------------------- # Test implementation +BR_STATE_TLV = 38 +BR_IF_ADDRS_TLV = 39 +BR_LOCAL_OMR_PREFIX_TLV = 40 +BR_DHCP6_PD_OMR_PREFIX_TLV = 41 +BR_LOCAL_OL_PREFIX_TLV = 42 +BR_FAVORED_OL_PREFIX_TLV = 43 + # Start first border router `br1` br1.srp_server_set_addr_mode('unicast') @@ -114,7 +121,7 @@ for br in all_brs: verify(int(br.br_count_peers().split()[0]) == 2) peers = br.br_get_peer_brs() verify(len(peers) == 2) - other_brs = all_brs + other_brs = [br1, br2, br3] other_brs.remove(br) for other_br in other_brs: rloc16 = other_br.get_rloc16() @@ -123,6 +130,38 @@ for br in all_brs: verify(len(ifaddrs) == 1) verify(ifaddrs[0].startswith('fe80:')) +# Validate network diagnostic BR TLVs, query BR2 from BR1. + +br2_rloc = br2.get_rloc_ip_addr() +result = br1.cli('networkdiagnostic get', br2_rloc, BR_STATE_TLV) +verify(len(result) == 2) +verify(result[1] == 'BR State: running') + +result = br1.cli('networkdiagnostic get', br2_rloc, BR_IF_ADDRS_TLV) +verify(len(result) > 2) +verify(result[1] == 'BR Infra-if IP6 Address List:') +verify(result[2].startswith(' - fe80:')) + +result = br1.cli('networkdiagnostic get', br2_rloc, BR_LOCAL_OMR_PREFIX_TLV) +verify(len(result) == 2) +verify(result[1].startswith('BR Local OMR Prefix: ')) +verify(result[1].split(': ')[1].strip() == br2.br_get_local_omrprefix()) + +result = br1.cli('networkdiagnostic get', br2_rloc, BR_DHCP6_PD_OMR_PREFIX_TLV) +verify(len(result) == 2) +verify(result[1].startswith('BR DHCPv6-PD OMR Prefix:')) +verify(result[1].split(': ')[1].strip() == '0:0:0:0::/64') + +result = br1.cli('networkdiagnostic get', br2_rloc, BR_LOCAL_OL_PREFIX_TLV) +verify(len(result) == 2) +verify(result[1].startswith('BR Local On-link Prefix: ')) +verify(result[1].split(': ')[1].strip() == br2.br_get_local_onlinkprefix()) + +result = br1.cli('networkdiagnostic get', br2_rloc, BR_FAVORED_OL_PREFIX_TLV) +verify(len(result) == 2) +verify(result[1].startswith('BR Favored On-link Prefix: ')) +verify(result[1].split(': ')[1].strip() == br2.br_get_favored_onlinkprefix()) + # Disable BR3 and validate that BR1 and BR2 detect this. # BR3 itself should continue to detect BR1 and BR2