From 0f4fbabc13815192f299e4dfc254256982b861d5 Mon Sep 17 00:00:00 2001 From: Jonathan Hui Date: Tue, 31 Mar 2026 21:14:46 -0700 Subject: [PATCH] [nexus] add 1_4_TREL_TC_4 for radio link (re)discovery (#12807) This commit implements Thread 1.4 Test Case 8.4 (TREL-8.4), "Radio Link (Re)discovery through Receive", using the Nexus simulation framework. The test validates the multi-radio behavior of a Border Router (DUT) and a Router neighbor, specifically focusing on TREL link state transitions and rediscovery mechanisms. Key test scenarios include: - Initial topology formation with a multi-radio BR (DUT), a multi-radio Router, and a 15.4-only End Device (ED). - Preference detection for TREL vs. 802.15.4 radio links. - Detection of TREL link failure and fallback to 802.15.4. - TREL radio link rediscovery triggered by receiving messages from a neighbor over the TREL interface. - Continued reachability via TREL when the 802.15.4 radio link is explicitly disabled. The implementation consists of: - tests/nexus/test_1_4_TREL_TC_4.cpp: C++ test logic for node configuration, state transitions, and message exchange. - tests/nexus/verify_1_4_TREL_TC_4.py: Python script for automated packet-level verification of radio link selection. - Integration into the Nexus build system and test runner. --- tests/nexus/CMakeLists.txt | 1 + tests/nexus/run_nexus_tests.sh | 1 + tests/nexus/test_1_4_TREL_TC_4.cpp | 383 ++++++++++++++++++++++++++++ tests/nexus/verify_1_4_TREL_TC_4.py | 198 ++++++++++++++ 4 files changed, 583 insertions(+) create mode 100644 tests/nexus/test_1_4_TREL_TC_4.cpp create mode 100644 tests/nexus/verify_1_4_TREL_TC_4.py diff --git a/tests/nexus/CMakeLists.txt b/tests/nexus/CMakeLists.txt index 37117a5b1..4df4b7abb 100644 --- a/tests/nexus/CMakeLists.txt +++ b/tests/nexus/CMakeLists.txt @@ -287,6 +287,7 @@ ot_nexus_test(1_3_DIAG_TC_2 "cert;nexus") ot_nexus_test(1_4_TREL_TC_1 "cert;nexus") ot_nexus_test(1_4_TREL_TC_2 "cert;nexus") ot_nexus_test(1_4_TREL_TC_3 "cert;nexus") +ot_nexus_test(1_4_TREL_TC_4 "cert;nexus") # Misc tests ot_nexus_test(border_admitter "core;nexus") diff --git a/tests/nexus/run_nexus_tests.sh b/tests/nexus/run_nexus_tests.sh index e8284072c..9c85d4860 100755 --- a/tests/nexus/run_nexus_tests.sh +++ b/tests/nexus/run_nexus_tests.sh @@ -222,6 +222,7 @@ DEFAULT_TESTS=( "1_4_TREL_TC_1" "1_4_TREL_TC_2" "1_4_TREL_TC_3" + "1_4_TREL_TC_4" ) # Use provided arguments or the default test list diff --git a/tests/nexus/test_1_4_TREL_TC_4.cpp b/tests/nexus/test_1_4_TREL_TC_4.cpp new file mode 100644 index 000000000..f52967da8 --- /dev/null +++ b/tests/nexus/test_1_4_TREL_TC_4.cpp @@ -0,0 +1,383 @@ +/* + * 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" + +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 = 120 * 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. + */ + + /** Use AllowList feature to specify links between nodes. */ + br.AllowList(router); + br.AllowList(ed); + + router.AllowList(br); + + ed.AllowList(br); + + SuccessOrQuit(br.Get().SetEnabled(true, kInfraIfIndex)); + SuccessOrQuit(router.Get().SetEnabled(true, kInfraIfIndex)); + + br.Form(); + nexus.AdvanceTime(kFormNetworkTime); + VerifyOrQuit(br.Get().IsLeader()); + + router.Join(br); + for (uint32_t i = 0; i < kAttachToRouterTime / 1000; i++) + { + nexus.AdvanceTime(1000); + if (router.Get().IsRouter()) + { + break; + } + } + VerifyOrQuit(router.Get().IsRouter()); + + ed.Join(br, Node::kAsFed); + for (uint32_t i = 0; i < kAttachToRouterTime / 1000; i++) + { + nexus.AdvanceTime(1000); + if (ed.Get().IsChild()) + { + break; + } + } + VerifyOrQuit(ed.Get().IsChild()); + VerifyOrQuit(ed.Get().GetParent().GetExtAddress() == br.Get().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().GetMeshLocalEid(), 0, 64, kPingTime); + } + + { + Neighbor::MultiRadioInfo info; + Neighbor *neighbor; + + neighbor = router.Get().FindNeighbor(br.Get().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().GetMeshLocalEid()); + nexus.AdvanceTime(kPingTime); + } + + { + Neighbor::MultiRadioInfo info; + Neighbor *neighbor; + + neighbor = router.Get().FindNeighbor(br.Get().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().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().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().FindNeighbor(router.Get().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().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().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; +} diff --git a/tests/nexus/verify_1_4_TREL_TC_4.py b/tests/nexus/verify_1_4_TREL_TC_4.py new file mode 100644 index 000000000..7bbb493c2 --- /dev/null +++ b/tests/nexus/verify_1_4_TREL_TC_4.py @@ -0,0 +1,198 @@ +#!/usr/bin/env python3 +# +# 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. +# + +import sys +import os + +# Add the current directory to sys.path to find verify_utils +CUR_DIR = os.path.dirname(os.path.abspath(__file__)) +sys.path.append(CUR_DIR) + +import verify_utils +from pktverify import consts + + +def verify(pv): + # 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 + + pkts = pv.pkts + pv.summary.show() + + BR_ETH = pv.vars['BR_ETH'] + ROUTER_ETH = pv.vars['ROUTER_ETH'] + + BR_MLEID = pv.vars['BR_MLEID'] + ROUTER_MLEID = pv.vars['ROUTER_MLEID'] + ED_MLEID = pv.vars['ED_MLEID'] + + BR_TREL_PORT = pv.vars['BR_TREL_PORT'] + ROUTER_TREL_PORT = pv.vars['ROUTER_TREL_PORT'] + + # 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. + print("Step 1: Form the topology.") + # Verify any Child ID Request exists to confirm topology formation started + pkts.copy().\ + filter_mle_cmd(consts.MLE_CHILD_ID_REQUEST).\ + must_next() + + # 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. + print("Step 2: Send 10 pings from Router to ED.") + # Verify pings from Router to BR use TREL + pkts.copy().\ + filter_eth_src(ROUTER_ETH).\ + filter(lambda p: p.eth.dst == BR_ETH).\ + filter(lambda p: hasattr(p, 'udp')).\ + filter(lambda p: p.udp.dstport == BR_TREL_PORT).\ + must_next() + + # Step 3 + # - Device: Router + # - Description (TREL-8.4): Harness disables the TREL connectivity on the Router. + # - Pass Criteria: + # - N/A + print("Step 3: Disable TREL connectivity on the Router.") + + # 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. + print("Step 4: Send 10 pings from Router to ED.") + # Pings should switch back to 15.4 (WPAN) + pkts.copy().\ + filter_ping_request().\ + filter_ipv6_src(ROUTER_MLEID).\ + filter_ipv6_dst(ED_MLEID).\ + filter(lambda p: hasattr(p, 'wpan')).\ + must_next() + + # 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. + print("Step 5: Send 5 pings from Router to ED.") + pkts.copy().\ + filter_ping_request().\ + filter_ipv6_src(ROUTER_MLEID).\ + filter_ipv6_dst(ED_MLEID).\ + must_next() + + # Step 6 + # - Device: Router + # - Description (TREL-8.4): Harness re-enables TREL connectivity on the Router. + # - Pass Criteria: + # - N/A + print("Step 6: Re-enable TREL connectivity on the Router.") + + # Step 7 + # - Device: Router + # - Description (TREL-8.4): Harness instructs device to send 300 UDP messages from Router to ED + # using mesh-local IPv6 addresses as source and destination. + # - Pass Criteria: + # - N/A + print("Step 7: Send 300 UDP messages from Router to ED.") + # Verify UDP messages (pings in our test) from Router to BR use TREL again (due to probe) + pkts.copy().\ + filter_eth_src(ROUTER_ETH).\ + filter(lambda p: p.eth.dst == BR_ETH).\ + filter(lambda p: hasattr(p, 'udp')).\ + filter(lambda p: p.udp.dstport == BR_TREL_PORT).\ + must_next() + + # Step 8 + # - Device: Router + # - Description (TREL-8.4): Harness disables 15.4 radio link on Router. + # - Pass Criteria: + # - N/A + print("Step 8: Disable 15.4 radio link on 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. + print("Step 9: Send 10 pings from ED to Router.") + # Path: ED -> BR (15.4) -> Router (TREL) + # BR -> Router (TREL) + pkts.copy().\ + filter_eth_src(BR_ETH).\ + filter(lambda p: p.eth.dst == ROUTER_ETH).\ + filter(lambda p: hasattr(p, 'udp')).\ + filter(lambda p: p.udp.dstport == ROUTER_TREL_PORT).\ + must_next() + # Router -> BR (TREL) + pkts.copy().\ + filter_eth_src(ROUTER_ETH).\ + filter(lambda p: p.eth.dst == BR_ETH).\ + filter(lambda p: hasattr(p, 'udp')).\ + filter(lambda p: p.udp.dstport == BR_TREL_PORT).\ + must_next() + + +if __name__ == '__main__': + verify_utils.run_main(verify)