[nexus] add test 1.2.LP.5.3.2 for CSL synchronized communication (#12604)

This commit adds Nexus test 1.2.LP.5.3.2 to validate that a Router
(DUT) can maintain a CSL connection with a Synchronized Sleepy End
Device (SSED) using various message types to trigger synchronization.

Changes:
- Implemented test_1_2_LP_5_3_2.cpp to simulate the topology of
  Leader, Router (DUT), and SSED.
- Added descriptive constants (kMsPerSecond, kUsPerMs, kEchoId,
  kCslWaitMultiplier) to test_1_2_LP_5_3_2.cpp to replace magic
  numbers.
- Implemented verify_1_2_LP_5_3_2.py for pcap-based verification of
  IEEE 802.15.4-2015 frames, CSL Information Elements, and timers.
- Updated test_1_2_LP_5_3_1.cpp to set CSL period and timeout
  explicitly using stack APIs instead of the removed kAsSsed mode.
- Removed kAsSsed JoinMode from Nexus::Node in favor of explicit
  CSL parameter configuration within test files.
- Added wpan.header_ie.csl.phase to verify_utils.py field mappings.
- Included the new test in CMakeLists.txt and run_nexus_tests.sh.
This commit is contained in:
Jonathan Hui
2026-03-04 14:07:43 -06:00
committed by GitHub
parent 49582b3d9f
commit 15645d3799
5 changed files with 714 additions and 0 deletions
+1
View File
@@ -216,6 +216,7 @@ ot_nexus_test(1_1_9_2_17 "cert;nexus")
ot_nexus_test(1_1_9_2_18 "cert;nexus")
ot_nexus_test(1_1_9_2_19 "cert;nexus")
ot_nexus_test(1_2_LP_5_3_1 "cert;nexus")
ot_nexus_test(1_2_LP_5_3_2 "cert;nexus")
# Misc tests
ot_nexus_test(border_admitter "core;nexus")
+1
View File
@@ -151,6 +151,7 @@ DEFAULT_TESTS=(
"1_1_9_2_18"
"1_1_9_2_19"
"1_2_LP_5_3_1"
"1_2_LP_5_3_2"
)
# Use provided arguments or the default test list
+407
View File
@@ -0,0 +1,407 @@
/*
* 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 "mac/data_poll_sender.hpp"
#include "platform/nexus_core.hpp"
#include "platform/nexus_node.hpp"
#include "thread/child_table.hpp"
namespace ot {
namespace Nexus {
/**
* Time conversion constants.
*/
static constexpr uint32_t kMsPerSecond = 1000;
static constexpr uint32_t kUsPerMs = 1000;
/**
* Time to advance for a node to form a network and become leader, in milliseconds.
*/
static constexpr uint32_t kFormNetworkTime = 13 * kMsPerSecond;
/**
* Time to advance for a node to join as a child and upgrade to a router, in milliseconds.
*/
static constexpr uint32_t kAttachToRouterTime = 200 * kMsPerSecond;
/**
* Time to advance for a node to join as a SSED.
*/
static constexpr uint32_t kAttachAsSsedTime = 20 * kMsPerSecond;
/**
* Time to wait in the test, in milliseconds.
*/
static constexpr uint32_t kWaitTime = 18 * kMsPerSecond;
/**
* CSL period in milliseconds.
*/
static constexpr uint32_t kCslPeriodMs = 500;
/**
* CSL period in units of 10 symbols.
*/
static constexpr uint32_t kCslPeriodInTenSymbols = kCslPeriodMs * kUsPerMs / kUsPerTenSymbols;
/**
* CSL timeout in seconds.
*/
static constexpr uint32_t kCslTimeout = 20;
/**
* CSL timeout in seconds to deactivate autosynchronization.
*/
static constexpr uint32_t kDeactivatedCslTimeout = 100;
/**
* UDP port for synchronization message.
*/
static constexpr uint16_t kUdpPort = 1234;
/**
* Payload size for ICMPv6 Echo Request.
*/
static constexpr uint16_t kEchoPayloadSize = 10;
/**
* Identifiers for ICMPv6 Echo Request.
*/
static constexpr uint16_t kEchoId1 = 0x01;
static constexpr uint16_t kEchoId2 = 0x02;
static constexpr uint16_t kEchoId3 = 0x03;
/**
* Multiplier for CSL period to allow for message delivery and response.
*/
static constexpr uint32_t kCslWaitMultiplier = 2;
/**
* Helper to send a UDP message.
*/
static void SendUdpMessage(Node &aNode, const Ip6::Address &aDestination, uint16_t aPort)
{
Message *message;
Ip6::MessageInfo messageInfo;
static const uint8_t kPayload[] = {0x01, 0x02, 0x03, 0x04};
message = aNode.Get<Ip6::Udp>().NewMessage();
VerifyOrQuit(message != nullptr);
SuccessOrQuit(message->AppendBytes(kPayload, sizeof(kPayload)));
messageInfo.SetPeerAddr(aDestination);
messageInfo.SetPeerPort(aPort);
Log("Sending UDP message from Node %lu (%s) to %s", ToUlong(aNode.GetId()), aNode.GetName(),
aDestination.ToString().AsCString());
SuccessOrQuit(aNode.Get<Ip6::Udp>().SendDatagram(*message, messageInfo));
}
/**
* Helper to verify CSL synchronization and timer reset on the router.
*/
static void VerifyCslTimerReset(Node &aRouter, Node &aSsed)
{
const Child *child = aRouter.Get<ChildTable>().FindChild(aSsed.Get<Mac::Mac>().GetExtAddress(), Child::kInStateAny);
VerifyOrQuit(child != nullptr);
VerifyOrQuit(child->IsCslSynchronized());
// Resetting to 0 means CslLastHeard is updated to current time.
Log("Checking CSL timer reset: Now=%u, LastHeard=%u", TimerMilli::GetNow().GetValue(),
child->GetCslLastHeard().GetValue());
VerifyOrQuit(TimerMilli::GetNow() - child->GetCslLastHeard() <= kCslPeriodMs);
}
void Test1_2_LP_5_3_2(void)
{
/**
* 5.3.2 CSL Synchronized Communication
*
* 5.3.2.1 Topology
* - Leader
* - Router 1 (DUT)
* - SSED 1
*
* 5.3.2.2 Purpose & Description
* The purpose of this test is to validate that the DUT is successfully able to sustain a CSL connection with a
* SSED that uses different types of messages to maintain its CSL Synchronization.
*
* 5.3.2.3 Configuration
* - Leader: Thread 1.2 Leader.
* - Router 1 (DUT): Thread 1.2 Router.
* - SSED_1: Thread 1.2 SSED.
* - SSED_1 is configured to have a CSL Synchronized Timeout value of 20s.
* - Set CSL Period = 500ms.
*
* Spec Reference | V1.2 Section
* -------------------------------|--------------
* CSL Synchronized Communication | 4.6.5.2.3
*/
Core nexus;
Node &leader = nexus.CreateNode();
Node &router1 = nexus.CreateNode();
Node &ssed1 = nexus.CreateNode();
leader.SetName("LEADER");
router1.SetName("ROUTER_1");
ssed1.SetName("SSED_1");
nexus.AdvanceTime(0);
Instance::SetLogLevel(kLogLevelNote);
/**
* Step 0: SSED_1
* - Description: Preconditions: Set CSL Synchronized Timeout = 20s, Set CSL Period = 500ms.
* - Pass Criteria: N/A.
*/
Log("Step 0: SSED_1");
// Pre-set CSL parameters on SSED_1 before it joins.
ssed1.Get<Mac::Mac>().SetCslPeriod(kCslPeriodInTenSymbols);
ssed1.Get<Mle::Mle>().SetCslTimeout(kCslTimeout);
/**
* Step 1: All
* - Description: Topology formation: Leader, DUT, SSED_1.
* - Pass Criteria: N/A.
*/
Log("Step 1: All");
/** Use AllowList feature to restrict the topology. */
leader.AllowList(router1);
router1.AllowList(leader);
router1.AllowList(ssed1);
ssed1.AllowList(router1);
leader.Form();
nexus.AdvanceTime(kFormNetworkTime);
VerifyOrQuit(leader.Get<Mle::Mle>().IsLeader());
router1.Join(leader);
nexus.AdvanceTime(kAttachToRouterTime);
VerifyOrQuit(router1.Get<Mle::Mle>().IsRouter());
/**
* Step 2: SSED_1
* - Description: Automatically attaches to the DUT.
* - Pass Criteria: The DUT MUST unicast MLE Child Update Response to SSED_1.
*/
Log("Step 2: SSED_1");
ssed1.Join(router1, Node::kAsSed);
// Override again after Join just in case Join() resets them to defaults.
ssed1.Get<Mac::Mac>().SetCslPeriod(kCslPeriodInTenSymbols);
ssed1.Get<Mle::Mle>().SetCslTimeout(kCslTimeout);
nexus.AdvanceTime(kAttachAsSsedTime);
VerifyOrQuit(ssed1.Get<Mle::Mle>().IsAttached());
/**
* Step 2a: SSED_1
* - Description: Harness instructs the device to deactivate autosynchronization.
* - Pass Criteria: N/A.
*/
Log("Step 2a: SSED_1");
// Deactivate autosynchronization by setting a very long CSL timeout on SSED_1.
ssed1.Get<Mle::Mle>().SetCslTimeout(kDeactivatedCslTimeout);
/**
* Step 3: Harness
* - Description: Harness waits for 18 seconds.
* - Pass Criteria: N/A.
*/
Log("Step 3: Harness");
nexus.AdvanceTime(kWaitTime);
/**
* Step 4: Leader
* - Description: Harness instructs the device to send a UDP message to SSED_1 mesh-local address to
* synchronize it.
* - Pass Criteria: SSED_1 MUST NOT send a MAC Data Request prior to receiving the UDP message from the
* Leader.
*/
Log("Step 4: Leader");
SendUdpMessage(leader, ssed1.Get<Mle::Mle>().GetMeshLocalEid(), kUdpPort);
/**
* Step 5: SSED_1
* - Description: Automatically responds to the DUT with an enhanced acknowledgement that contains CSL IEs.
* - Pass Criteria: The CSL unsynchronized timer on the Router (DUT) should be reset to 0.
*/
Log("Step 5: SSED_1");
nexus.AdvanceTime(kCslPeriodMs); // Allow time for message delivery and ACK.
VerifyCslTimerReset(router1, ssed1);
/**
* Step 6: Harness
* - Description: Harness waits for 18 seconds.
* - Pass Criteria: N/A.
*/
Log("Step 6: Harness");
nexus.AdvanceTime(kWaitTime);
/**
* Step 7: Leader
* - Description: Harness verifies connectivity by instructing the device to send an ICMPv6 Echo Request to
* the SSED_1 mesh-local address via the DUT.
* - Pass Criteria:
* - SSED_1 MUST NOT send a MAC Data Request prior to receiving the ICMPv6 Echo Request from the Leader.
* - The Leader MUST receive an ICMPv6 Echo Reply from SSED_1.
*/
Log("Step 7: Leader");
leader.SendEchoRequest(ssed1.Get<Mle::Mle>().GetMeshLocalEid(), kEchoId1, kEchoPayloadSize);
nexus.AdvanceTime(kCslPeriodMs * kCslWaitMultiplier); // Allow time for Echo Request and Reply.
/**
* Step 8: Harness
* - Description: Harness waits for 18 seconds.
* - Pass Criteria: N/A.
*/
Log("Step 8: Harness");
nexus.AdvanceTime(kWaitTime);
/**
* Step 9: SSED_1
* - Description: Harness instructs the device to send a MAC Data Request message containing CSL IEs to the
* DUT.
* - Pass Criteria: The CSL unsynchronized timer on the Router (DUT) should be reset to 0.
*/
Log("Step 9: SSED_1");
SuccessOrQuit(ssed1.Get<DataPollSender>().SendDataPoll());
nexus.AdvanceTime(kCslPeriodMs);
VerifyCslTimerReset(router1, ssed1);
/**
* Step 10: Harness
* - Description: Harness waits for 18 seconds.
* - Pass Criteria: N/A.
*/
Log("Step 10: Harness");
nexus.AdvanceTime(kWaitTime);
/**
* Step 11: Leader
* - Description: Harness verifies connectivity by instructing the device to send an ICMPv6 Echo Request to
* the SSED_1 mesh-local address via the DUT.
* - Pass Criteria:
* - SSED_1 MUST NOT send a MAC Data Request prior to receiving the ICMPv6 Echo Request from the Leader.
* - The Leader MUST receive an ICMPv6 Echo Reply from SSED_1.
*/
Log("Step 11: Leader");
leader.SendEchoRequest(ssed1.Get<Mle::Mle>().GetMeshLocalEid(), kEchoId2, kEchoPayloadSize);
nexus.AdvanceTime(kCslPeriodMs * kCslWaitMultiplier);
/**
* Step 12: Harness
* - Description: Harness waits for 18 seconds.
* - Pass Criteria: N/A.
*/
Log("Step 12: Harness");
nexus.AdvanceTime(kWaitTime);
/**
* Step 13: SSED_1
* - Description: Harness instructs the device to send a UDP Message to the DUT.
* - Pass Criteria:
* - The CSL unsynchronized timer on the Router (DUT) should be reset to 0.
* - Check that the 802.15.4 Frame Header includes following Information Elements:
* - CSL Period IE (Check value of this TLV)
* - CSL Phase IE
* - Compare the value of this TLV with the expected value.
*/
Log("Step 13: SSED_1");
SendUdpMessage(ssed1, router1.Get<Mle::Mle>().GetMeshLocalEid(), kUdpPort);
nexus.AdvanceTime(kCslPeriodMs);
VerifyCslTimerReset(router1, ssed1);
/**
* Step 14: Router (DUT)
* - Description: Automatically sends an Enhanced ACK to SSED_1.
* - Pass Criteria:
* - The Information Elements MUST NOT be included.
* - The Enhanced ACK must occur within the ACK timeout.
*/
Log("Step 14: Router (DUT)");
/**
* Step 15: Harness
* - Description: Harness waits for 18 seconds.
* - Pass Criteria: N/A.
*/
Log("Step 15: Harness");
nexus.AdvanceTime(kWaitTime);
/**
* Step 16: Leader
* - Description: Harness verifies connectivity by instructing the device to send an ICMPv6 Echo Request to
* the SSED_1 mesh-local address via the DUT.
* - Pass Criteria:
* - SSED1 MUST NOT send a MAC Data Request prior to receiving the ICMPv6 Echo Request from the Leader.
* - The Leader MUST receive an ICMPv6 Echo Reply from SSED_1.
*/
Log("Step 16: Leader");
leader.SendEchoRequest(ssed1.Get<Mle::Mle>().GetMeshLocalEid(), kEchoId3, kEchoPayloadSize);
nexus.AdvanceTime(kCslPeriodMs * kCslWaitMultiplier);
nexus.SaveTestInfo("test_1_2_LP_5_3_2.json");
}
} // namespace Nexus
} // namespace ot
int main(void)
{
ot::Nexus::Test1_2_LP_5_3_2();
printf("All tests passed\n");
return 0;
}
+304
View File
@@ -0,0 +1,304 @@
#!/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 os
import sys
# 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
from pktverify.null_field import nullField
CSL_PERIOD_MS = 500
def _has_csl_ie(p):
csl_period_in_10_symbols_units = CSL_PERIOD_MS * 1000 // consts.US_PER_TEN_SYMBOLS
return (p.wpan.version == 2 and p.wpan.ie_present == 1 and consts.CSL_IE_ID in p.wpan.header_ie.id and
p.wpan.header_ie.csl.period == csl_period_in_10_symbols_units and
p.wpan.header_ie.csl.phase is not nullField)
def _must_not_have_data_request_from_ssed1(pkts, start_pkt, end_pkt, ssed_1, router_1_rloc16):
pkts.range((start_pkt.number if start_pkt else 1, 0), (end_pkt.number, 0)).\
filter_wpan_src64(ssed_1).\
filter_wpan_dst16(router_1_rloc16).\
filter_wpan_cmd(consts.WPAN_DATA_REQUEST).\
must_not_next()
def verify(pv):
# 5.3.2 CSL Synchronized Communication
#
# 5.3.2.1 Topology
# - Leader
# - Router 1 (DUT)
# - SSED 1
#
# 5.3.2.2 Purpose & Description
# The purpose of this test is to validate that the DUT is successfully able to sustain a CSL connection with a
# SSED that uses different types of messages to maintain its CSL Synchronization.
#
# 5.3.2.3 Configuration
# - Leader: Thread 1.2 Leader.
# - Router 1 (DUT): Thread 1.2 Router.
# - SSED_1: Thread 1.2 SSED.
# - SSED_1 is configured to have a CSL Synchronized Timeout value of 20s.
# - Set CSL Period = 500ms.
#
# Spec Reference | V1.2 Section
# -------------------------------|--------------
# CSL Synchronized Communication | 4.6.5.2.3
pkts = pv.pkts
pv.summary.show()
LEADER = pv.vars['LEADER']
LEADER_ML_EID = pv.vars['LEADER_MLEID']
ROUTER_1 = pv.vars['ROUTER_1']
ROUTER_1_RLOC16 = pv.vars['ROUTER_1_RLOC16']
SSED_1 = pv.vars['SSED_1']
SSED_1_ML_EID = pv.vars['SSED_1_MLEID']
SSED_1_RLOC16 = pv.vars['SSED_1_RLOC16']
# Step 0: SSED_1
# - Description: Preconditions: Set CSL Synchronized Timeout = 20s, Set CSL Period = 500ms.
# - Pass Criteria: N/A.
print("Step 0: SSED_1 configuration")
# Step 1: All
# - Description: Topology formation: Leader, DUT, SSED_1.
# - Pass Criteria: N/A.
print("Step 1: Topology formation")
# Step 2: SSED_1
# - Description: Automatically attaches to the DUT.
# - Pass Criteria: The DUT MUST unicast MLE Child Update Response to SSED_1.
print("Step 2: SSED_1 attaches to DUT")
child_update_resp = pkts.filter_wpan_src64(ROUTER_1).\
filter_wpan_dst64(SSED_1).\
filter_mle_cmd(consts.MLE_CHILD_UPDATE_RESPONSE).\
must_next()
# Step 2a: SSED_1
# - Description: Harness instructs the device to deactivate autosynchronization.
# - Pass Criteria: N/A.
print("Step 2a: Deactivate autosynchronization")
# Step 3: Harness
# - Description: Harness waits for 18 seconds.
# - Pass Criteria: N/A.
print("Step 3: Harness waits for 18 seconds")
# Step 4: Leader
# - Description: Harness instructs the device to send a UDP message to SSED_1 mesh-local address to synchronize it.
# - Pass Criteria: SSED_1 MUST NOT send a MAC Data Request prior to receiving the UDP message from the Leader.
print("Step 4: Leader sends UDP to SSED_1")
udp_pkt = pkts.range((child_update_resp.number, 0)).\
filter_wpan_src64(LEADER).\
filter_wpan_dst16(ROUTER_1_RLOC16).\
filter(lambda p: p.udp).\
filter_ipv6_dst(SSED_1_ML_EID).\
must_next()
# SSED_1 MUST NOT send a MAC Data Request prior to receiving the UDP message from the Leader.
_must_not_have_data_request_from_ssed1(pkts, child_update_resp, udp_pkt, SSED_1, ROUTER_1_RLOC16)
# Step 5: SSED_1
# - Description: Automatically responds to the DUT with an enhanced acknowledgement that contains CSL IEs.
# - Pass Criteria: The CSL unsynchronized timer on the Router (DUT) should be reset to 0.
print("Step 5: SSED_1 responds with Enhanced ACK containing CSL IEs")
# Enhanced ACK for the forwarded UDP message (Router 1 to SSED_1)
udp_fwd = pkts.range((udp_pkt.number, 0)).\
filter_wpan_src64(ROUTER_1).\
filter_wpan_dst16(SSED_1_RLOC16).\
filter(lambda p: p.udp).\
filter_ipv6_dst(SSED_1_ML_EID).\
filter(lambda p: p.wpan.version == 2).\
must_next()
# The DUT MUST receive an Enhanced ACK from SSED_1
ack_step5 = pkts.range((udp_fwd.number, 0)).\
filter_wpan_ack().\
filter(_has_csl_ie).\
must_next()
# Step 6: Harness
# - Description: Harness waits for 18 seconds.
# - Pass Criteria: N/A.
print("Step 6: Harness waits for 18 seconds")
# Step 7: Leader
# - Description: Harness verifies connectivity by instructing the device to send an ICMPv6 Echo Request to the
# SSED_1 mesh-local address via the DUT.
# - Pass Criteria:
# - SSED_1 MUST NOT send a MAC Data Request prior to receiving the ICMPv6 Echo Request from the Leader.
# - The Leader MUST receive an ICMPv6 Echo Reply from SSED_1.
print("Step 7: Leader sends Echo Request to SSED_1")
echo_req_1 = pkts.range((ack_step5.number, 0)).\
filter_ping_request().\
filter_wpan_src64(LEADER).\
filter_wpan_dst16(ROUTER_1_RLOC16).\
filter_ipv6_dst(SSED_1_ML_EID).\
must_next()
# SSED_1 MUST NOT send a MAC Data Request prior to receiving the ICMPv6 Echo Request from the Leader.
_must_not_have_data_request_from_ssed1(pkts, udp_fwd, echo_req_1, SSED_1, ROUTER_1_RLOC16)
echo_reply_1 = pkts.range((echo_req_1.number, 0)).\
filter_ping_reply(identifier=echo_req_1.icmpv6.echo.identifier).\
filter_wpan_src64(SSED_1).\
filter_wpan_dst16(ROUTER_1_RLOC16).\
must_next()
# Step 8: Harness
# - Description: Harness waits for 18 seconds.
# - Pass Criteria: N/A.
print("Step 8: Harness waits for 18 seconds")
# Step 9: SSED_1
# - Description: Harness instructs the device to send a MAC Data Request message containing CSL IEs to the DUT.
# - Pass Criteria: The CSL unsynchronized timer on the Router (DUT) should be reset to 0.
print("Step 9: SSED_1 sends MAC Data Request with CSL IEs")
# We look for the Data Request starting from echo_req_1 because it could be delayed until Step 9.
step9_data_req = pkts.range((echo_req_1.number, 0)).\
filter_wpan_src64(SSED_1).\
filter_wpan_dst16(ROUTER_1_RLOC16).\
filter_wpan_cmd(consts.WPAN_DATA_REQUEST).\
filter(_has_csl_ie).\
must_next()
# Step 10: Harness
# - Description: Harness waits for 18 seconds.
# - Pass Criteria: N/A.
print("Step 10: Harness waits for 18 seconds")
# Step 11: Leader
# - Description: Harness verifies connectivity by instructing the device to send an ICMPv6 Echo Request to the
# SSED_1 mesh-local address via the DUT.
# - Pass Criteria:
# - SSED_1 MUST NOT send a MAC Data Request prior to receiving the ICMPv6 Echo Request from the Leader.
# - The Leader MUST receive an ICMPv6 Echo Reply from SSED_1.
print("Step 11: Leader sends Echo Request to SSED_1")
# Start search from whichever packet was later: echo_reply_1 or step9_data_req.
last_pkt_step9 = echo_reply_1 if echo_reply_1.number > step9_data_req.number else step9_data_req
echo_req_2 = pkts.range((last_pkt_step9.number, 0)).\
filter_ping_request().\
filter_wpan_src64(LEADER).\
filter_wpan_dst16(ROUTER_1_RLOC16).\
filter_ipv6_dst(SSED_1_ML_EID).\
must_next()
# SSED_1 MUST NOT send a MAC Data Request prior to receiving the ICMPv6 Echo Request from the Leader.
_must_not_have_data_request_from_ssed1(pkts, step9_data_req, echo_req_2, SSED_1, ROUTER_1_RLOC16)
echo_reply_2 = pkts.range((echo_req_2.number, 0)).\
filter_ping_reply(identifier=echo_req_2.icmpv6.echo.identifier).\
filter_wpan_src64(SSED_1).\
filter_wpan_dst16(ROUTER_1_RLOC16).\
must_next()
# Step 12: Harness
# - Description: Harness waits for 18 seconds.
# - Pass Criteria: N/A.
print("Step 12: Harness waits for 18 seconds")
# Step 13: SSED_1
# - Description: Harness instructs the device to send a UDP Message to the DUT.
# - Pass Criteria:
# - The CSL unsynchronized timer on the Router (DUT) should be reset to 0.
# - Check that the 802.15.4 Frame Header includes following Information Elements:
# - CSL Period IE (Check value of this TLV)
# - CSL Phase IE
# - Compare the value of this TLV with the expected value.
print("Step 13: SSED_1 sends UDP to DUT with CSL IEs")
# UDP could also be delayed until Step 13 if Echo Request 2 was delayed.
step13_udp = pkts.range((echo_req_2.number, 0)).\
filter_wpan_src64(SSED_1).\
filter_wpan_dst16(ROUTER_1_RLOC16).\
filter(lambda p: p.udp).\
filter(_has_csl_ie).\
must_next()
# Step 14: Router (DUT)
# - Description: Automatically sends an Enhanced ACK to SSED_1.
# - Pass Criteria: The DUT MUST send an enhanced ACK to SSED_1:
# - The Information Elements MUST NOT be included.
# - The Enhanced ACK must occur within the ACK timeout.
print("Step 14: Router sends Enhanced ACK (no IEs)")
ack_step14 = pkts.range((step13_udp.number, 0)).\
filter_wpan_ack().\
filter(lambda p: p.wpan.version == 2 and p.wpan.ie_present == 0).\
must_next()
# Step 15: Harness
# - Description: Harness waits for 18 seconds.
# - Pass Criteria: N/A.
print("Step 15: Harness waits for 18 seconds")
# Step 16: Leader
# - Description: Harness verifies connectivity by instructing the device to send an ICMPv6 Echo Request to the
# SSED_1 mesh-local address via the DUT.
# - Pass Criteria:
# - SSED1 MUST NOT send a MAC Data Request prior to receiving the ICMPv6 Echo Request from the Leader.
# - The Leader MUST receive an ICMPv6 Echo Reply from SSED_1.
print("Step 16: Leader sends Echo Request to SSED_1")
# Ensure we search after both echo_reply_2 and ack_step14.
last_pkt_step14 = echo_reply_2 if echo_reply_2.number > ack_step14.number else ack_step14
echo_req_3 = pkts.range((last_pkt_step14.number, 0)).\
filter_ping_request().\
filter_wpan_src64(LEADER).\
filter_wpan_dst16(ROUTER_1_RLOC16).\
filter_ipv6_dst(SSED_1_ML_EID).\
must_next()
# SSED1 MUST NOT send a MAC Data Request prior to receiving the ICMPv6 Echo Request from the Leader.
_must_not_have_data_request_from_ssed1(pkts, last_pkt_step14, echo_req_3, SSED_1, ROUTER_1_RLOC16)
pkts.range((echo_req_3.number, 0)).\
filter_ping_reply(identifier=echo_req_3.icmpv6.echo.identifier).\
filter_wpan_src64(SSED_1).\
filter_wpan_dst16(ROUTER_1_RLOC16).\
must_next()
if __name__ == '__main__':
verify_utils.run_main(verify)
+1
View File
@@ -271,6 +271,7 @@ def apply_patches():
layer_fields._LAYER_FIELDS['coap.tlv.period'] = layer_fields._auto
layer_fields._LAYER_FIELDS['coap.tlv.scan_duration'] = layer_fields._auto
layer_fields._LAYER_FIELDS['coap.tlv.energy_list'] = layer_fields._bytes
layer_fields._LAYER_FIELDS['wpan.header_ie.csl.phase'] = layer_fields._auto
layer_fields._LAYER_FIELDS['wpan_tap.ch_num'] = layer_fields._auto
layer_fields._LAYER_FIELDS['wpan-tap.ch_num'] = layer_fields._auto
layer_fields._LAYER_FIELDS['coap.tlv.ext_pan_id'] = layer_fields._bytes