/* * Copyright (c) 2026, The OpenThread Authors. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holder nor the * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include #include "platform/nexus_core.hpp" #include "platform/nexus_node.hpp" #include "thread/net_diag.hpp" namespace ot { namespace Nexus { /** * Time to advance for a node to form a network and become leader, in milliseconds. */ static constexpr uint32_t kFormNetworkTime = 13 * 1000; /** * Time to advance for a node to join as a child and upgrade to a router, in milliseconds. */ static constexpr uint32_t kAttachToRouterTime = 200 * 1000; /** * Time to advance for the network to stabilize after nodes have attached. */ static constexpr uint32_t kStabilizationTime = 10 * 1000; /** * Time to advance for the diagnostic response to be received. */ static constexpr uint32_t kDiagResponseTime = 5 * 1000; /** * Time to wait for DIAG_GET to complete (20 seconds). */ static constexpr uint32_t kWait20Seconds = 20 * 1000; /** * Time to wait before next step (2 seconds). */ static constexpr uint32_t kWait2Seconds = 2 * 1000; /** * Number of routers in the topology. */ static constexpr uint8_t kNumRouters = 15; /** * Base diagnostic TLV types used in Steps 2 and 8. */ static constexpr uint8_t kBaseDiagGetTlvs[] = { NetDiag::Tlv::kExtMacAddress, NetDiag::Tlv::kAddress16, NetDiag::Tlv::kMode, NetDiag::Tlv::kConnectivity, NetDiag::Tlv::kRoute, NetDiag::Tlv::kLeaderData, NetDiag::Tlv::kNetworkData, NetDiag::Tlv::kIp6AddressList, NetDiag::Tlv::kChannelPages, }; /** * MAC Counters diagnostic TLV type used in Steps 3, 6, and 7. */ static constexpr uint8_t kMacCountersTlv[] = {NetDiag::Tlv::kMacCounters}; void Test5_7_2(void) { /** * 5.7.2 CoAP Diagnostic Get Query and Answer Commands – REED * * 5.7.2.1 Topology * - Leader * - Router_1 * - REED_1 (DUT) * - (Additional routers as needed to satisfy REED conditions, typically a total of 16 active routers) * * 5.7.2.2 Purpose & Description * This test case exercises the Diagnostic Get Query and Answer commands as part of the Network Management. This * test case topology is specific to REED DUTs. * * Spec Reference | V1.1 Section | V1.3.0 Section * -----------------|--------------|--------------- * Diag Commands | 10.11.2 | 10.11.2 */ Core nexus; Node &leader = nexus.CreateNode(); Node &reed1 = nexus.CreateNode(); Node *routers[kNumRouters]; leader.SetName("LEADER"); reed1.SetName("REED_1"); for (uint8_t i = 0; i < kNumRouters; i++) { routers[i] = &nexus.CreateNode(); routers[i]->SetName("ROUTER", i + 1); } nexus.AdvanceTime(0); SuccessOrQuit(Instance::SetGlobalLogLevel(kLogLevelNote)); Log("---------------------------------------------------------------------------------------"); Log("Step 1: All"); /** * Step 1: All * - Description: Ensure topology is formed correctly. * - Pass Criteria: N/A */ for (uint8_t i = 0; i < kNumRouters; i++) { AllowLinkBetween(leader, *routers[i]); } AllowLinkBetween(reed1, *routers[0]); leader.Form(); nexus.AdvanceTime(kFormNetworkTime); for (uint8_t i = 0; i < kNumRouters; i++) { routers[i]->Join(leader); } nexus.AdvanceTime(kAttachToRouterTime); for (uint8_t i = 0; i < kNumRouters; i++) { VerifyOrQuit(routers[i]->Get().IsRouter()); } reed1.Join(*routers[0], Node::kAsFtd); nexus.AdvanceTime(kAttachToRouterTime); nexus.AdvanceTime(kStabilizationTime); VerifyOrQuit(reed1.Get().IsChild()); const Ip6::Address &reedRloc = reed1.Get().GetMeshLocalRloc(); Log("---------------------------------------------------------------------------------------"); Log("Step 2: Leader"); /** * Step 2: Leader * - Description: Harness instructs the device to send DIAG_GET.req to the DUT’s Routing Locator (RLOC) for the * following diagnostic TLV types: * - TLV Type 0 – MAC Extended Address (64-bit) * - TLV Type 1 - MAC Address (16-bit) * - TLV Type 2 - Mode (Capability information) * - TLV Type 4 – Connectivity * - TLV Type 5 – Route64 * - TLV Type 6 – Leader Data * - TLV Type 7 – Network Data * - TLV Type 8 – IPv6 address list * - TLV Type 17 – Channel Pages * - Pass Criteria: * - The DUT MUST respond with a DIAG_GET.rsp response containing the requested diagnostic TLVs: * - CoAP Response Code: 2.04 Changed * - CoAP Payload: * - TLV Type 0 - MAC Extended Address (64-bit) * - TLV Type 1 - MAC Address (16-bit) * - TLV Type 2 - Mode (Capability information) * - TLV Type 4 – Connectivity * - TLV Type 5 – Route64 (optional) * - TLV Type 6 – Leader Data * - TLV Type 7 – Network Data * - TLV Type 8 – IPv6 address list * - TLV Type 17 – Channel Pages * - The presence of each TLV MUST be validated. Where possible, the value of the TLVs MUST be validated. */ SuccessOrQuit(leader.Get().SendDiagnosticGet(reedRloc, kBaseDiagGetTlvs, sizeof(kBaseDiagGetTlvs), nullptr, nullptr)); nexus.AdvanceTime(kDiagResponseTime); Log("---------------------------------------------------------------------------------------"); Log("Step 3: Leader"); /** * Step 3: Leader * - Description: Harness instructs the device to send DIAG_GET.req to the DUT’s Routing Locator (RLOC) for the * following diagnostic TLV type: * - TLV Type 9 - MAC Counters * - Pass Criteria: * - The DUT MUST respond with a DIAG_GET.rsp response containing the requested diagnostic TLV: * - CoAP Response Code: 2.04 Changed * - CoAP Payload: * - TLV Type 9 - MAC Counters * - TLV Type 9 - MAC Counters MUST contain a list of MAC Counters. */ SuccessOrQuit(leader.Get().SendDiagnosticGet(reedRloc, kMacCountersTlv, sizeof(kMacCountersTlv), nullptr, nullptr)); nexus.AdvanceTime(kDiagResponseTime); Log("---------------------------------------------------------------------------------------"); Log("Step 4: Leader"); /** * Step 4: Leader * - Description: Harness instructs the device to send DIAG_GET.req to the DUT’s Routing Locator (RLOC) for the * following diagnostic TLV types: * - TLV Type 3 – Timeout * - TLV Type 16 – Child Table TLV * - Pass Criteria: * - The DUT MUST respond with a DIAG_GET.rsp response containing the required diagnostic TLV payload: * - CoAP Response Code: 2.04 Changed * - CoAP Payload: * - The Timeout TLV MUST NOT be present. */ uint8_t tlvTypes4[] = {NetDiag::Tlv::kTimeout, NetDiag::Tlv::kChildTable}; SuccessOrQuit( leader.Get().SendDiagnosticGet(reedRloc, tlvTypes4, sizeof(tlvTypes4), nullptr, nullptr)); nexus.AdvanceTime(kDiagResponseTime); Log("---------------------------------------------------------------------------------------"); Log("Step 5: Leader"); /** * Step 5: Leader * - Description: Harness instructs the device to send DIAG_GET.req to the DUT’s Routing Locator (RLOC) for the * following diagnostic TLV types: * - TLV Type 14 – Battery Level * - TLV Type 15 – Supply Voltage * - Pass Criteria: * - The DUT MUST respond with a DIAG_GET.rsp response optionally containing the requested diagnostic TLVs: * - CoAP Response Code: 2.04 Changed * - CoAP Payload: * - TLV Type 14 – Battery Level (optional) * - TLV Type 15 – Supply Voltage (optional) */ uint8_t tlvTypes5[] = {NetDiag::Tlv::kBatteryLevel, NetDiag::Tlv::kSupplyVoltage}; SuccessOrQuit( leader.Get().SendDiagnosticGet(reedRloc, tlvTypes5, sizeof(tlvTypes5), nullptr, nullptr)); nexus.AdvanceTime(kDiagResponseTime); Log("---------------------------------------------------------------------------------------"); Log("Step 5a: Test Harness"); /** * Step 5a: Test Harness * - Description: Harness waits 20 seconds to allow DIAG_GET to complete. * - Pass Criteria: N/A */ nexus.AdvanceTime(kWait20Seconds); Log("---------------------------------------------------------------------------------------"); Log("Step 6: Leader"); /** * Step 6: Leader * - Description: Harness instructs the device to send DIAG_RST.ntf to DUT’s Routing Locator (RLOC) for the * following diagnostic TLV type: * - TLV Type 9 - MAC Counters * - Pass Criteria: * - The DUT MUST respond with a CoAP response: * - CoAP Response Code: 2.04 Changed */ SuccessOrQuit( leader.Get().SendDiagnosticReset(reedRloc, kMacCountersTlv, sizeof(kMacCountersTlv))); nexus.AdvanceTime(kDiagResponseTime); Log("---------------------------------------------------------------------------------------"); Log("Step 6a: Test Harness"); /** * Step 6a: Test Harness * - Description: Harness waits ONLY 2 seconds before executing next step. * - Pass Criteria: N/A */ nexus.AdvanceTime(kWait2Seconds); Log("---------------------------------------------------------------------------------------"); Log("Step 7: Leader"); /** * Step 7: Leader * - Description: Harness instructs the device to send DIAG_GET.req to the DUT’s Routing Locator (RLOC) for the * following diagnostic TLV type: * - TLV Type 9 - MAC Counters * - Pass Criteria: * - The DUT MUST respond with a DIAG_GET.rsp response containing the requested diagnostic TLV: * - CoAP Response Code: 2.04 Changed * - CoAP Payload: * - TLV Type 9 - MAC Counters * - TLV Type 9 - MAC Counters MUST contain a list of MAC Counters with 0 value or less than value returned in * step 3. */ SuccessOrQuit(leader.Get().SendDiagnosticGet(reedRloc, kMacCountersTlv, sizeof(kMacCountersTlv), nullptr, nullptr)); nexus.AdvanceTime(kDiagResponseTime); Log("---------------------------------------------------------------------------------------"); Log("Step 8: Leader"); /** * Step 8: Leader * - Description: Harness instructs the device to send DIAG_GET.query to Realm-Local All-Nodes multicast address * (FF03::1) for the following diagnostic TLV types: * - TLV Type 0 – MAC Extended Address (64-bit) * - TLV Type 1 - MAC Address (16-bit) * - TLV Type 2 - Mode (Capability information) * - TLV Type 4 – Connectivity * - TLV Type 5 – Route64 * - TLV Type 6 – Leader Data * - TLV Type 7 – Network Data * - TLV Type 8 – IPv6 address list * - TLV Type 17 – Channel Pages * - Pass Criteria: * - The DUT MUST respond with a DIAG_GET.ans response containing the requested diagnostic TLVs: * - CoAP Payload: * - TLV Type 0 - MAC Extended Address (64-bit) * - TLV Type 1 - MAC Address (16-bit) * - TLV Type 2 - Mode (Capability information) * - TLV Type 4 – Connectivity * - TLV Type 5 – Route64 (optional) * - TLV Type 6 – Leader Data * - TLV Type 7 – Network Data * - TLV Type 8 – IPv6 address list * - TLV Type 17 – Channel Pages * - The presence of each TLV MUST be validated. Where possible, the value of the TLVs MUST be validated. */ SuccessOrQuit(leader.Get().SendDiagnosticGet( Ip6::Address::GetRealmLocalAllNodesMulticast(), kBaseDiagGetTlvs, sizeof(kBaseDiagGetTlvs), nullptr, nullptr)); nexus.AdvanceTime(kDiagResponseTime); nexus.SaveTestInfo("test_1_1_5_7_2.json"); } } // namespace Nexus } // namespace ot int main(void) { ot::Nexus::Test5_7_2(); printf("All tests passed\n"); return 0; }