mirror of
https://github.com/espressif/openthread.git
synced 2026-06-05 21:14:49 +00:00
15e1c233bf
This commit refactors several Nexus diagnostic test cases to use the existing `Mle::GetMeshLocalRloc()` method instead of manually assembling the RLOC by combining the mesh-local prefix and the node's RLOC16. This improves code readability and adheres to the standard pattern for retrieving a node's Routing Locator.
256 lines
10 KiB
C++
256 lines
10 KiB
C++
/*
|
||
* 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 <stdio.h>
|
||
#include <string.h>
|
||
|
||
#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 = 15 * 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 diagnostic response to be received.
|
||
*/
|
||
static constexpr uint32_t kDiagResponseTime = 5 * 1000;
|
||
|
||
/**
|
||
* Time to wait in Step 4, in milliseconds.
|
||
*/
|
||
static constexpr uint32_t kWaitTime = 4 * 1000;
|
||
|
||
void TestDiagTc2(const char *aJsonFile)
|
||
{
|
||
/**
|
||
* 4.2. [1.4] [CERT] Get Diagnostics – End Device
|
||
*
|
||
* 4.2.2. Topology
|
||
* - Leader_1
|
||
* - Router_1
|
||
* - TD_1 (DUT)
|
||
*
|
||
* Spec Reference | Section
|
||
* -----------------|---------
|
||
* Thread 1.4 | 4.2
|
||
*/
|
||
|
||
Core nexus;
|
||
|
||
Node &leader1 = nexus.CreateNode();
|
||
Node &router1 = nexus.CreateNode();
|
||
Node &td1 = nexus.CreateNode();
|
||
|
||
leader1.SetName("Leader_1");
|
||
router1.SetName("Router_1");
|
||
td1.SetName("TD_1");
|
||
|
||
nexus.AdvanceTime(0);
|
||
|
||
SuccessOrQuit(Instance::SetGlobalLogLevel(kLogLevelNote));
|
||
|
||
AllowLinkBetween(leader1, router1);
|
||
AllowLinkBetween(router1, td1);
|
||
|
||
Log("---------------------------------------------------------------------------------------");
|
||
Log("Step 1: Enable the devices in order. Leader configures its Network Data with an OMR prefix.");
|
||
|
||
/**
|
||
* Step 1
|
||
* - Device: Leader, Router_1
|
||
* - Description (DIAG-4.2): Enable the devices in order. The DUT is not yet activated. Leader
|
||
* configures its Network Data with an OMR prefix. Note: the OMR prefix can be added using an
|
||
* OT CLI command such as: "prefix add 2001:dead:beef:cafe::/64 paros med"
|
||
* - Pass Criteria:
|
||
* - Single Thread Network is formed with Leader and Router_1.
|
||
*/
|
||
leader1.Form();
|
||
nexus.AdvanceTime(kFormNetworkTime);
|
||
VerifyOrQuit(leader1.Get<Mle::Mle>().IsLeader());
|
||
|
||
router1.Join(leader1);
|
||
nexus.AdvanceTime(kAttachToRouterTime);
|
||
VerifyOrQuit(router1.Get<Mle::Mle>().IsRouter());
|
||
|
||
NetworkData::OnMeshPrefixConfig omrPrefixConfig;
|
||
SuccessOrQuit(omrPrefixConfig.GetPrefix().FromString("2001:dead:beef:cafe::/64"));
|
||
omrPrefixConfig.mPreferred = true;
|
||
omrPrefixConfig.mSlaac = true;
|
||
omrPrefixConfig.mDhcp = false;
|
||
omrPrefixConfig.mDefaultRoute = true;
|
||
omrPrefixConfig.mOnMesh = true;
|
||
omrPrefixConfig.mStable = true;
|
||
omrPrefixConfig.mPreference = NetworkData::kRoutePreferenceMedium;
|
||
SuccessOrQuit(leader1.Get<NetworkData::Local>().AddOnMeshPrefix(omrPrefixConfig));
|
||
leader1.Get<NetworkData::Notifier>().HandleServerDataUpdated();
|
||
|
||
nexus.AdvanceTime(30 * 1000); // Wait for network data propagation
|
||
|
||
Log("---------------------------------------------------------------------------------------");
|
||
Log("Step 1b: TD_1 (DUT) Enable.");
|
||
|
||
/**
|
||
* Step 1b
|
||
* - Device: TD_1 (DUT)
|
||
* - Description (DIAG-4.2): Enable.
|
||
* - Pass Criteria:
|
||
* - N/A
|
||
*/
|
||
td1.Join(router1, Node::kAsMed);
|
||
nexus.AdvanceTime(kAttachToRouterTime);
|
||
VerifyOrQuit(td1.Get<Mle::Mle>().IsChild());
|
||
|
||
Log("---------------------------------------------------------------------------------------");
|
||
Log("Step 2: Leader instructs device to send DIAG_GET.req to DUT's RLOC for Diagnostic TLV types.");
|
||
|
||
/**
|
||
* Step 2
|
||
* - Device: Leader
|
||
* - Description (DIAG-4.2): Harness instructs device to send DIAG_GET.req to DUT's RLOC for the
|
||
* following Diagnostic TLV types: Type 19: Max Child Timeout TLV, Type 23: EUI-64 TLV, Type
|
||
* 24: Version TLV, Type 25: Vendor Name TLV, Type 26: Vendor Model TLV, Type 27: Vendor SW
|
||
* Version TLV, Type 28: Thread Stack Version TLV
|
||
* - Pass Criteria:
|
||
* - N/A
|
||
*/
|
||
Ip6::Address td1Rloc = td1.Get<Mle::Mle>().GetMeshLocalRloc();
|
||
|
||
uint8_t tlvTypesStep2[] = {
|
||
NetDiag::Tlv::kMaxChildTimeout, NetDiag::Tlv::kEui64, NetDiag::Tlv::kVersion,
|
||
NetDiag::Tlv::kVendorName, NetDiag::Tlv::kVendorModel, NetDiag::Tlv::kVendorSwVersion,
|
||
NetDiag::Tlv::kThreadStackVersion,
|
||
};
|
||
SuccessOrQuit(leader1.Get<NetDiag::Client>().SendDiagnosticGet(td1Rloc, tlvTypesStep2, sizeof(tlvTypesStep2),
|
||
nullptr, nullptr));
|
||
|
||
Log("---------------------------------------------------------------------------------------");
|
||
Log("Step 3: TD_1 (DUT) Automatically responds either with 1. DIAG_GET.rsp or 2. CoAP response 4.04.");
|
||
|
||
/**
|
||
* Step 3
|
||
* - Device: TD_1 (DUT)
|
||
* - Description (DIAG-4.2): Automatically responds either with 1. DIAG_GET.rsp containing the
|
||
* requested Diagnostic TLVs, or a particular subset of those TLVs; 2. CoAP response 4.04 Not
|
||
* Found in case no diagnostics are supported at all.
|
||
* - Pass Criteria:
|
||
* - For case 1, the CoAP status code MUST be 2.04 Changed.
|
||
* - Each TLV (as requested in step 2) that is present in the response MUST be validated. Any
|
||
* number of TLVs MAY be present, from 0 to 7, depending on DUT's diagnostics support level.
|
||
* - The Max Child Timeout TLV (Type 19) is not expected to be present. However, if present it
|
||
* MUST be '0' (zero).
|
||
* - Value of EUI-64 TLV (Type 23) MUST be non-zero.
|
||
* - Value of Version TLV (Type 24) MUST be >= '5'.
|
||
* - Value of Vendor Name TLV (Type 25) MUST have length >= 1.
|
||
* - Value of Vendor Model TLV (Type 26) MUST have length >= 1.
|
||
* - Value of Vendor SW Version TLV (Type 27) MUST have length >= 5.
|
||
* - Value of Thread Stack Version TLV (Type 28) MUST have length >= 5.
|
||
* - For case 2, the CoAP status code is 4.04 and TLVs MUST NOT be present.
|
||
*/
|
||
nexus.AdvanceTime(kDiagResponseTime);
|
||
|
||
Log("---------------------------------------------------------------------------------------");
|
||
Log("Step 4: Harness waits for 4 seconds.");
|
||
|
||
/**
|
||
* Step 4
|
||
* - Device: N/A
|
||
* - Description (DIAG-4.2): Harness waits for 4 seconds. Note: this is done only to influence
|
||
* diagnostic Time fields that are verified in later steps.
|
||
* - Pass Criteria:
|
||
* - N/A
|
||
*/
|
||
nexus.AdvanceTime(kWaitTime);
|
||
|
||
Log("---------------------------------------------------------------------------------------");
|
||
Log("Step 4: Leader instructs device to send DIAG_GET.req unicast to DUT's RLOC for MLE Counters TLV.");
|
||
|
||
/**
|
||
* Step 4
|
||
* - Device: Leader
|
||
* - Description (DIAG-4.2): Harness instructs device to send DIAG_GET.req unicast to DUT's RLOC
|
||
* for the following Diagnostic TLV types: Type 34: MLE Counters TLV
|
||
* - Pass Criteria:
|
||
* - N/A
|
||
*/
|
||
uint8_t tlvTypesStep4[] = {NetDiag::Tlv::kMleCounters};
|
||
SuccessOrQuit(leader1.Get<NetDiag::Client>().SendDiagnosticGet(td1Rloc, tlvTypesStep4, sizeof(tlvTypesStep4),
|
||
nullptr, nullptr));
|
||
|
||
Log("---------------------------------------------------------------------------------------");
|
||
Log("Step 5: TD_1 (DUT) Automatically responds with DIAG_GET.rsp containing the requested Diagnostic TLVs.");
|
||
|
||
/**
|
||
* Step 5
|
||
* - Device: TD_1 (DUT)
|
||
* - Description (DIAG-4.2): Automatically responds with DIAG_GET.rsp containing the requested
|
||
* Diagnostic TLVs.
|
||
* - Pass Criteria:
|
||
* - The DUT must send DIAG_GET.rsp
|
||
* - The presence of each TLV (as requested in the previous step) MUST be validated.
|
||
* - In the MLE Counters TLV (Type 34):
|
||
* - Radio Disabled Counter MUST be '0'
|
||
* - Detached Role Counter MUST be '1'
|
||
* - Child Role Counter MUST be '1'
|
||
* - Router Role Counter MUST be '0'
|
||
* - Leader Role Counter MUST be '0'
|
||
* - Attach Attempts Counter MUST be >= 1
|
||
* - Partition ID Changes Counter MUST be '1'
|
||
* - New Parent Counter MUST be '0'
|
||
* - Total Tracking Time MUST be > 4000
|
||
* - Child Role Time MUST be >= 1
|
||
* - Router Role Time MUST be '0'
|
||
* - Leader Role Time MUST be '0'
|
||
*/
|
||
nexus.AdvanceTime(kDiagResponseTime);
|
||
|
||
nexus.SaveTestInfo(aJsonFile);
|
||
}
|
||
|
||
} // namespace Nexus
|
||
} // namespace ot
|
||
|
||
int main(int argc, char *argv[])
|
||
{
|
||
const char *jsonFile = (argc > 1) ? argv[argc - 1] : "test_1_3_DIAG_TC_2.json";
|
||
|
||
ot::Nexus::TestDiagTc2(jsonFile);
|
||
printf("All tests passed\n");
|
||
return 0;
|
||
}
|