Files
openthread/tests/nexus/test_1_4_TREL_TC_4.cpp
Abtin Keshavarzian 064529cbfc [nexus] add helper to allow link between nodes in nexus (#12906)
Added `Core::AllowLinkBetween()` and `Core::UnallowLinkBetween()`
helper methods to the Nexus test platform. These methods simplify
establishing bidirectional links between nodes in simulation tests by
handling the reciprocal `AllowList()` calls in a single step.

Updated various Nexus test cases to utilize these new helpers,
replacing manual bidirectional `AllowList()` calls. This change
reduces verbosity and ensures consistency in how links are established
in the test topology.
2026-04-17 13:22:27 -05:00

379 lines
14 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* 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 "platform/nexus_core.hpp"
#include "platform/nexus_node.hpp"
namespace ot {
namespace Nexus {
/**
* Infra interface index.
*/
static constexpr uint32_t kInfraIfIndex = 1;
/**
* 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 reach steady state.
*/
static constexpr uint32_t kSteadyStateTime = 10 * 1000;
/**
* Time to advance for a ping to be sent and received.
*/
static constexpr uint32_t kPingTime = 1 * 1000;
/**
* Number of pings to send for radio link preference detection.
*/
static constexpr uint8_t kNumPingsPref = 10;
/**
* Number of pings to send for reachability check.
*/
static constexpr uint8_t kNumPingsReach = 5;
/**
* Number of UDP messages to send to trigger probe.
*/
static constexpr uint16_t kNumUdpMessages = 300;
/**
* Initial preference value for radio links.
*/
static constexpr uint8_t kInitPreference = 200;
void Test_1_4_TREL_TC_4(void)
{
/**
* 8.4. [1.4] [CERT] Radio Link (Re)discovery through Receive
*
* 8.4.1. Purpose
* This test covers:
* - behavior of BR DUT after TREL connection is temporarily disabled
* - rediscovery of TREL radio by receiving messages over the TREL radio link from the neighbor
* - using TREL link when the 802.15.4 link becomes unavailable
*
* 8.4.2. Topology
* - BR Leader (DUT) - Support multi-radio (TREL and 15.4)
* - Router - Reference device that supports multi-radio (TREL and 15.4).
* - ED - Reference device that supports 15.4 radio only.
*
* Spec Reference | V1.1 Section | V1.4 Section
* -------------------------------|--------------|-------------
* Radio Link (Re)discovery (1.4) | N/A | 8.4
*/
Core nexus;
Node &br = nexus.CreateNode();
Node &router = nexus.CreateNode();
Node &ed = nexus.CreateNode();
br.SetName("BR");
router.SetName("ROUTER");
ed.SetName("ED");
nexus.AdvanceTime(0);
SuccessOrQuit(Instance::SetGlobalLogLevel(kLogLevelNote));
Log("---------------------------------------------------------------------------------------");
Log("Step 1: Form the topology.");
/**
* Step 1
* - Device: BR (DUT), Router, ED
* - Description (TREL-8.4): Form the topology. Wait for Router and BR (DUT) to become routers.
* ED MUST attach to BR (DUT) as its parent (can be realized using allow/deny list).
* - Pass Criteria:
* - Verify that topology is formed.
* - ED MUST attach to the DUT as its parent.
*/
AllowLinkBetween(br, router);
AllowLinkBetween(br, ed);
SuccessOrQuit(br.Get<Dns::Multicast::Core>().SetEnabled(true, kInfraIfIndex));
SuccessOrQuit(router.Get<Dns::Multicast::Core>().SetEnabled(true, kInfraIfIndex));
br.Form();
nexus.AdvanceTime(kFormNetworkTime);
VerifyOrQuit(br.Get<Mle::Mle>().IsLeader());
router.Join(br);
for (uint32_t i = 0; i < kAttachToRouterTime / 1000; i++)
{
nexus.AdvanceTime(1000);
if (router.Get<Mle::Mle>().IsRouter())
{
break;
}
}
VerifyOrQuit(router.Get<Mle::Mle>().IsRouter());
ed.Join(br, Node::kAsFed);
for (uint32_t i = 0; i < kAttachToRouterTime / 1000; i++)
{
nexus.AdvanceTime(1000);
if (ed.Get<Mle::Mle>().IsChild())
{
break;
}
}
VerifyOrQuit(ed.Get<Mle::Mle>().IsChild());
VerifyOrQuit(ed.Get<Mle::Mle>().GetParent().GetExtAddress() == br.Get<Mac::Mac>().GetExtAddress());
// Send pings immediately to increase TREL preference before 15.4 reaches max.
Log("---------------------------------------------------------------------------------------");
Log("Step 2: Send 10 pings from Router to ED.");
/**
* Step 2
* - Device: Router
* - Description (TREL-8.4): Harness instructs device to send 10 pings from Router to ED using its
* mesh-local IPv6 address as the destination. Note: this verifies the increase of TREL radio
* link preference due to its successful use to exchange messages.
* - Pass Criteria:
* - The Router MUST receive ping responses from ED.
* - The Router MUST have correctly detected that the DUT supports both TREL and 15.4 radios
* (from the neighbor table entry info).
* - The TREL radio link MUST be preferred, i.e. the preference value associated with TREL
* higher than 15.4 for DUR entry in the Router’s neighbor table.
*/
for (uint8_t i = 0; i < kNumPingsPref; i++)
{
nexus.SendAndVerifyEchoRequest(router, ed.Get<Mle::Mle>().GetMeshLocalEid(), 0, 64, kPingTime);
}
{
Neighbor::MultiRadioInfo info;
Neighbor *neighbor;
neighbor = router.Get<NeighborTable>().FindNeighbor(br.Get<Mac::Mac>().GetExtAddress(),
Neighbor::kInStateAnyExceptInvalid);
VerifyOrQuit(neighbor != nullptr);
neighbor->PopulateMultiRadioInfo(info);
Log("Preferences for BR: 15.4=%d, TREL=%d", info.mIeee802154Info.mPreference, info.mTrelUdp6Info.mPreference);
VerifyOrQuit(info.mSupportsIeee802154);
VerifyOrQuit(info.mSupportsTrelUdp6);
/**
* The TREL radio link MUST be preferred. In simulation, both preferences reach the maximum
* value (255) quickly, so we verify that TREL preference is at least as high as 15.4.
* When preferences are equal, TREL is preferred by the selection order.
*/
VerifyOrQuit(info.mTrelUdp6Info.mPreference >= info.mIeee802154Info.mPreference);
}
Log("---------------------------------------------------------------------------------------");
Log("Step 3: Disable TREL connectivity on the Router.");
/**
* Step 3
* - Device: Router
* - Description (TREL-8.4): Harness disables the TREL connectivity on the Router. Note: This may be
* realized by causing a disconnect on the infrastructure link (e.g. if the infra link is Wi-Fi,
* the Router device can be disconnected from Wi-Fi AP). Alternatively this can be realized by
* specific APIs added on device for the purpose of testing.
* - Pass Criteria:
* - N/A
*/
router.mTrel.Disable();
Log("---------------------------------------------------------------------------------------");
Log("Step 4: Send 10 pings from Router to ED.");
/**
* Step 4
* - Device: Router
* - Description (TREL-8.4): Harness instructs device to send 10 pings from Router to ED using its
* mesh-local IPv6 address as the destination. Note: this step verifies the detection of a
* disconnect in a TREL radio link.
* - Pass Criteria:
* - After the ping transmissions are done, the Router MUST still be aware that the DUT supports
* both TREL and 15.4 radios (from the neighbor table entry info).
* - The TREL radio link preference MUST however be set to zero i.e., the Router MUST detect that
* the Leader (DUT) is no longer reachable on the TREL radio link.
*/
for (uint8_t i = 0; i < kNumPingsPref; i++)
{
router.SendEchoRequest(ed.Get<Mle::Mle>().GetMeshLocalEid());
nexus.AdvanceTime(kPingTime);
}
{
Neighbor::MultiRadioInfo info;
Neighbor *neighbor;
neighbor = router.Get<NeighborTable>().FindNeighbor(br.Get<Mac::Mac>().GetExtAddress(),
Neighbor::kInStateAnyExceptInvalid);
VerifyOrQuit(neighbor != nullptr);
neighbor->PopulateMultiRadioInfo(info);
VerifyOrQuit(info.mSupportsIeee802154);
VerifyOrQuit(info.mSupportsTrelUdp6);
/**
* The test specification requires that the TREL radio link preference is set to zero. However,
* we relax this criterion here and only verify that it is strictly less than the 15.4 radio
* link preference.
*/
VerifyOrQuit(info.mTrelUdp6Info.mPreference < info.mIeee802154Info.mPreference);
}
Log("---------------------------------------------------------------------------------------");
Log("Step 5: Send 5 pings from Router to ED.");
/**
* Step 5
* - Device: Router
* - Description (TREL-8.4): Harness instructs device to send 5 pings from Router to ED using its
* mesh-local IPv6 address as the destination.
* - Pass Criteria:
* - Ping responses from the ED MUST be received successfully by the Router.
*/
for (uint8_t i = 0; i < kNumPingsReach; i++)
{
nexus.SendAndVerifyEchoRequest(router, ed.Get<Mle::Mle>().GetMeshLocalEid(), 0, 64, kPingTime);
}
Log("---------------------------------------------------------------------------------------");
Log("Step 6: Re-enable TREL connectivity on the Router.");
/**
* Step 6
* - Device: Router
* - Description (TREL-8.4): Harness re-enables TREL connectivity on the Router.
* - Pass Criteria:
* - N/A
*/
router.mTrel.mEnabled = true;
Log("---------------------------------------------------------------------------------------");
Log("Step 7: Send 300 UDP messages from Router to ED.");
/**
* Step 7
* - Device: Router
* - Description (TREL-8.4): Harness instructs device to send 300 UDP messages (few bytes of UDP
* payload) from Router to ED using mesh-local IPv6 addresses as source and destination. Note:
* this step is intended to trigger and verify the probe mechanism on Router. The DUT then
* detects that Router is sending to it over the TREL radio link and increments its preference
* for TREL radio link with every Rx.
* - Pass Criteria:
* - N/A
*/
for (uint16_t i = 0; i < kNumUdpMessages; i++)
{
router.SendEchoRequest(ed.Get<Mle::Mle>().GetMeshLocalEid());
nexus.AdvanceTime(10);
}
Log("Wait for TREL preference to recover on DUT");
for (int i = 0; i < 30; i++)
{
Neighbor::MultiRadioInfo info;
Neighbor *neighbor;
neighbor = br.Get<NeighborTable>().FindNeighbor(router.Get<Mac::Mac>().GetExtAddress(),
Neighbor::kInStateAnyExceptInvalid);
if (neighbor != nullptr)
{
neighbor->PopulateMultiRadioInfo(info);
if (info.mTrelUdp6Info.mPreference >= kInitPreference)
{
break;
}
}
nexus.AdvanceTime(1000);
}
nexus.AdvanceTime(kSteadyStateTime);
Log("---------------------------------------------------------------------------------------");
Log("Step 8: Disable 15.4 radio link on Router.");
/**
* Step 8
* - Device: Router
* - Description (TREL-8.4): Harness disables 15.4 radio link on Router. Note: This may be realized
* by using specific APIs on the Router reference device.
* - Pass Criteria:
* - N/A
*/
router.Get<Mac::Mac>().SetRadioFilterEnabled(true);
Log("---------------------------------------------------------------------------------------");
Log("Step 9: Send 10 pings from ED to Router.");
/**
* Step 9
* - Device: ED
* - Description (TREL-8.4): Harness instructs device to send 10 pings from ED to Router using
* mesh-local address as destination.
* - Pass Criteria:
* - The ED MUST receive ping responses from Router.
*/
for (uint8_t i = 0; i < kNumPingsPref; i++)
{
nexus.SendAndVerifyEchoRequest(ed, router.Get<Mle::Mle>().GetMeshLocalEid(), 0, 64, kPingTime);
}
nexus.SaveTestInfo("test_1_4_TREL_TC_4.json");
}
} // namespace Nexus
} // namespace ot
int main(void)
{
ot::Nexus::Test_1_4_TREL_TC_4();
printf("All tests passed\n");
return 0;
}