/* * 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 "mac/mac.hpp" #include "platform/nexus_core.hpp" #include "platform/nexus_node.hpp" #include "thread/child_table.hpp" #include "thread/neighbor.hpp" #include "thread/neighbor_table.hpp" #include "thread/network_data_local.hpp" #include "thread/network_data_notifier.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 a node to join as a child, in milliseconds. */ static constexpr uint32_t kAttachAsChildTime = 5 * 1000; /** * Child timeout value in seconds. */ static constexpr uint32_t kChildTimeout = 10; /** * Time to advance for the network to stabilize, in milliseconds. */ static constexpr uint32_t kStabilizationTime = 10 * 1000; /** * IPv6 Prefix 1. */ static const char kPrefix1[] = "2001::/64"; /** * IPv6 Prefix 2. */ static const char kPrefix2[] = "2002::/64"; void Test7_1_8(const char *aJsonFile) { /** * 7.1.8 Network data propagation – Border Router as End Device in Thread network; registers new server data * information after network is formed * * 7.1.8.1 Topology * - FED_1 is configured to require complete network data. (Mode TLV) * * 7.1.8.2 Purpose & Description * The purpose of this test case is to verify that when global prefix information is set on the FED, the DUT * properly disseminates the associated network data. It also verifies that the DUT sends revised server data * information to the Leader when the FED is removed. * * Spec Reference | V1.1 Section | V1.3.0 Section * -------------------------------------------|--------------------|-------------------- * Thread Network Data / Stable Thread | 5.13 / 5.14 / 5.15 | 5.13 / 5.14 / 5.15 * Network Data / Network Data Propagation | | */ Core nexus; Node &leader = nexus.CreateNode(); Node &router1 = nexus.CreateNode(); // DUT Node &fed1 = nexus.CreateNode(); leader.SetName("LEADER"); router1.SetName("ROUTER_1"); fed1.SetName("FED_1"); nexus.AdvanceTime(0); SuccessOrQuit(Instance::SetGlobalLogLevel(kLogLevelNote)); Log("---------------------------------------------------------------------------------------"); Log("Step 1: All"); /** * Step 1: All * - Description: Topology Ensure topology is formed correctly. * - Pass Criteria: N/A. */ AllowLinkBetween(leader, router1); AllowLinkBetween(router1, fed1); leader.Form(); nexus.AdvanceTime(kFormNetworkTime); VerifyOrQuit(leader.Get().IsLeader()); router1.Join(leader); nexus.AdvanceTime(kAttachToRouterTime); VerifyOrQuit(router1.Get().IsRouter()); fed1.Get().SetTimeout(kChildTimeout); fed1.Join(router1, Node::kAsFed); nexus.AdvanceTime(kAttachAsChildTime); VerifyOrQuit(fed1.Get().IsChild()); nexus.AdvanceTime(kStabilizationTime); Log("---------------------------------------------------------------------------------------"); Log("Step 2: FED_1"); /** * Step 2: FED_1 * - Description: Harness configures device with the following On-Mesh Prefix Set: * - Prefix 1: P_Prefix=2001::/64 P_stable=1 P_default=1 P_slaac=1 P_on_mesh=1 P_preferred=1 * - Prefix 2: P_Prefix=2002::/64 P_stable=0 P_default=1 P_slaac=1 P_on_mesh=1 P_preferred=1 * - Automatically sends a CoAP Server Data Notification message with the server’s information (Prefix, Border * Router) to the Leader. * - Pass Criteria: N/A. */ { NetworkData::OnMeshPrefixConfig config; config.Clear(); SuccessOrQuit(config.GetPrefix().FromString(kPrefix1)); config.mStable = true; config.mDefaultRoute = true; config.mSlaac = true; config.mOnMesh = true; config.mPreferred = true; SuccessOrQuit(fed1.Get().AddOnMeshPrefix(config)); config.Clear(); SuccessOrQuit(config.GetPrefix().FromString(kPrefix2)); config.mStable = false; config.mDefaultRoute = true; config.mSlaac = true; config.mOnMesh = true; config.mPreferred = true; SuccessOrQuit(fed1.Get().AddOnMeshPrefix(config)); fed1.Get().HandleServerDataUpdated(); } nexus.AdvanceTime(kStabilizationTime); Log("---------------------------------------------------------------------------------------"); Log("Step 3: Leader"); /** * Step 3: Leader * - Description: Automatically transmits a 2.04 Changed CoAP response to the DUT. Automatically transmits * multicast MLE Data Response with the new information collected, adding also 6LoWPAN ID TLV for the prefix set * on FED_1. * - Pass Criteria: N/A. */ nexus.AdvanceTime(kStabilizationTime); Log("---------------------------------------------------------------------------------------"); Log("Step 4: Router_1 (DUT)"); /** * Step 4: Router_1 (DUT) * - Description: Automatically transmits multicast MLE Data Response with the new information collected, adding * also 6LoWPAN ID TLV for the prefix set on FED_1. * - Pass Criteria: The DUT MUST send a multicast MLE Data Response. */ nexus.AdvanceTime(kStabilizationTime); Log("---------------------------------------------------------------------------------------"); Log("Step 5: FED_1"); /** * Step 5: FED_1 * - Description: Harness silently powers-down FED_1 and waits for Router_1 to remove FED_1 from its neighbor * table. * - Pass Criteria: N/A. */ fed1.Get().Stop(); // Wait for the child to be timed out by the parent router. nexus.AdvanceTime((kChildTimeout + 2) * 1000); // Verify that the child is removed from the neighbor table. VerifyOrQuit(router1.Get().FindNeighbor(fed1.Get().GetExtAddress()) == nullptr, "FED_1 should be removed after timeout"); nexus.AdvanceTime(kStabilizationTime); Log("---------------------------------------------------------------------------------------"); Log("Step 6: Router_1 (DUT)"); /** * Step 6: Router_1 (DUT) * - Description: Automatically notifies Leader of removed server’s (FED_1’s) RLOC16. * - Pass Criteria: The DUT MUST send a CoAP Server Data Notification message to the Leader containing only the * removed server’s RLOC16: * - CoAP Request URI: coap://[]:MM/a/sd * - CoAP Payload: RLOC16 TLV. */ nexus.AdvanceTime(kStabilizationTime); nexus.SaveTestInfo(aJsonFile); } } // namespace Nexus } // namespace ot int main(int argc, char *argv[]) { ot::Nexus::Test7_1_8((argc > 2) ? argv[2] : "test_1_1_7_1_8.json"); printf("All tests passed\n"); return 0; }