mirror of
https://github.com/espressif/openthread.git
synced 2026-08-16 23:57:46 +00:00
This commit adds Nexus test case 9.2.17 which verifies the behavior of an orphaned end device as it searches for a new parent using MLE Announce messages. Implementation details: - tests/nexus/test_9_2_17.cpp: C++ test execution logic. Implements the 3-node topology (Leader_1, Leader_2, ED_1) using direct method calls. Manages RF isolation by manipulating the Mac Filter AllowList. Sets log level to note. Uses MED mode for the DUT to enable MLE Announce behavior. Also explicitly sets the channel mask for Leader_2 for robustness. - tests/nexus/verify_9_2_17.py: PCAP verification script. Verifies initial MLE Advertisements on separate channels, DUT sending MLE Parent Requests on the primary channel, followed by MLE Announce on the secondary channel. Verifies Leader_2 sending MLE Announce on the primary channel and DUT successfully attaching to Leader_2. - tests/nexus/run_nexus_tests.sh: Added 9_2_17 to default test list. - tests/nexus/CMakeLists.txt: Added nexus_9_2_17 target. - Included full test specification as inline comments in both C++ and Python code.
This commit is contained in:
@@ -209,6 +209,7 @@ ot_nexus_test(9_2_13 "cert;nexus")
|
||||
ot_nexus_test(9_2_14 "cert;nexus")
|
||||
ot_nexus_test(9_2_15 "cert;nexus")
|
||||
ot_nexus_test(9_2_16 "cert;nexus")
|
||||
ot_nexus_test(9_2_17 "cert;nexus")
|
||||
|
||||
# Misc tests
|
||||
ot_nexus_test(border_admitter "core;nexus")
|
||||
|
||||
@@ -145,6 +145,7 @@ DEFAULT_TESTS=(
|
||||
"9_2_14"
|
||||
"9_2_15"
|
||||
"9_2_16"
|
||||
"9_2_17"
|
||||
)
|
||||
|
||||
# Use provided arguments or the default test list
|
||||
|
||||
@@ -0,0 +1,343 @@
|
||||
/*
|
||||
* 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 "meshcop/dataset.hpp"
|
||||
#include "platform/nexus_core.hpp"
|
||||
#include "platform/nexus_node.hpp"
|
||||
#include "thread/mle.hpp"
|
||||
#include "thread/thread_netif.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 a network, in milliseconds.
|
||||
*/
|
||||
static constexpr uint32_t kJoinTime = 10 * 1000;
|
||||
|
||||
/**
|
||||
* Time to advance for the DUT to recognize that its parent is gone, in milliseconds.
|
||||
*/
|
||||
static constexpr uint32_t kParentLossTime = 60 * 1000;
|
||||
|
||||
/**
|
||||
* Time to advance for the DUT to send Parent Request and receive no response, in milliseconds.
|
||||
*/
|
||||
static constexpr uint32_t kParentSelectionTime = 10 * 1000;
|
||||
|
||||
/**
|
||||
* Time to advance for the DUT to send MLE Announce and receive MLE Announce response, in milliseconds.
|
||||
*/
|
||||
static constexpr uint32_t kAnnounceTime = 10 * 1000;
|
||||
|
||||
/**
|
||||
* Time to advance for the DUT to attach to a new parent, in milliseconds.
|
||||
*/
|
||||
static constexpr uint32_t kAttachTime = 20 * 1000;
|
||||
|
||||
/**
|
||||
* Time to wait for ICMPv6 Echo response, in milliseconds.
|
||||
*/
|
||||
static constexpr uint32_t kEchoTimeout = 5000;
|
||||
|
||||
/**
|
||||
* Primary Channel.
|
||||
*/
|
||||
static constexpr uint16_t kPrimaryChannel = 11;
|
||||
|
||||
/**
|
||||
* Secondary Channel.
|
||||
*/
|
||||
static constexpr uint16_t kSecondaryChannel = 12;
|
||||
|
||||
/**
|
||||
* Leader_1 PAN ID.
|
||||
*/
|
||||
static constexpr uint16_t kLeader1PanId = 0x1111;
|
||||
|
||||
/**
|
||||
* Leader_2 PAN ID.
|
||||
*/
|
||||
static constexpr uint16_t kLeader2PanId = 0x2222;
|
||||
|
||||
/**
|
||||
* Leader_1 Active Timestamp.
|
||||
*/
|
||||
static constexpr uint64_t kLeader1Timestamp = 10;
|
||||
|
||||
/**
|
||||
* Leader_2 Active Timestamp.
|
||||
*/
|
||||
static constexpr uint64_t kLeader2Timestamp = 20;
|
||||
|
||||
/**
|
||||
* Network Key.
|
||||
*/
|
||||
static const uint8_t kNetworkKey[] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
|
||||
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff};
|
||||
|
||||
void Test9_2_17(void)
|
||||
{
|
||||
/**
|
||||
* 9.2.17 Orphaned End Devices
|
||||
*
|
||||
* 9.2.17.1 Topology
|
||||
* - Leader_1
|
||||
* - Leader_2
|
||||
* - ED_1 (DUT)
|
||||
*
|
||||
* 9.2.17.2 Purpose & Description
|
||||
* The purpose of this test case to validate end device functionality when its Parent is no longer available and
|
||||
* searches for a new Parent using MLE Announce messages.
|
||||
*
|
||||
* Spec Reference | V1.1 Section | V1.3.0 Section
|
||||
* ---------------------|--------------|---------------
|
||||
* Orphaned End Devices | 8.7.7 | 8.7.7
|
||||
*/
|
||||
|
||||
Core nexus;
|
||||
|
||||
Node &leader1 = nexus.CreateNode();
|
||||
Node &leader2 = nexus.CreateNode();
|
||||
Node &dut = nexus.CreateNode();
|
||||
|
||||
leader1.SetName("LEADER_1");
|
||||
leader2.SetName("LEADER_2");
|
||||
dut.SetName("DUT");
|
||||
|
||||
nexus.AdvanceTime(0);
|
||||
|
||||
Instance::SetLogLevel(kLogLevelNote);
|
||||
|
||||
Log("---------------------------------------------------------------------------------------");
|
||||
Log("Step 1: All");
|
||||
|
||||
/**
|
||||
* Step 1: All
|
||||
* - Description: Form the two topologies and ensure the DUT is attached to Leader_1
|
||||
* - Pass Criteria: Ensure topology is formed correctly. Verify that Leader_1 & Leader_2 are sending MLE
|
||||
* Advertisements on separate channels.
|
||||
*/
|
||||
|
||||
leader1.AllowList(dut);
|
||||
dut.AllowList(leader1);
|
||||
|
||||
leader2.AllowList(dut);
|
||||
dut.AllowList(leader2);
|
||||
|
||||
// Leader 1 <-> DUT is allowed.
|
||||
// Leader 2 <-> DUT is initially blocked by radio channel and different PAN ID, but here we also use AllowList.
|
||||
// We start with Leader 2 being reachable but on different channel.
|
||||
// Actually, to fully control connectivity as per spec, we'll unallow Leader 2 for now.
|
||||
leader2.UnallowList(dut);
|
||||
dut.UnallowList(leader2);
|
||||
|
||||
dut.Get<Mle::Mle>().SetTimeout(20);
|
||||
|
||||
{
|
||||
MeshCoP::Dataset::Info datasetInfo;
|
||||
|
||||
SuccessOrQuit(datasetInfo.GenerateRandom(leader1.GetInstance()));
|
||||
|
||||
datasetInfo.Set<MeshCoP::Dataset::kChannel>(kPrimaryChannel);
|
||||
datasetInfo.Set<MeshCoP::Dataset::kPanId>(kLeader1PanId);
|
||||
{
|
||||
NetworkKey &networkKey = datasetInfo.Update<MeshCoP::Dataset::kNetworkKey>();
|
||||
memcpy(networkKey.m8, kNetworkKey, sizeof(networkKey));
|
||||
}
|
||||
{
|
||||
MeshCoP::Timestamp timestamp;
|
||||
timestamp.SetSeconds(kLeader1Timestamp);
|
||||
timestamp.SetTicks(0);
|
||||
datasetInfo.Set<MeshCoP::Dataset::kActiveTimestamp>(timestamp);
|
||||
}
|
||||
datasetInfo.Set<MeshCoP::Dataset::kChannelMask>((1 << kPrimaryChannel) | (1 << kSecondaryChannel));
|
||||
|
||||
leader1.Get<MeshCoP::ActiveDatasetManager>().SaveLocal(datasetInfo);
|
||||
leader1.Get<ThreadNetif>().Up();
|
||||
SuccessOrQuit(leader1.Get<Mle::Mle>().Start());
|
||||
}
|
||||
|
||||
{
|
||||
MeshCoP::Dataset::Info datasetInfo;
|
||||
|
||||
SuccessOrQuit(datasetInfo.GenerateRandom(leader2.GetInstance()));
|
||||
|
||||
datasetInfo.Set<MeshCoP::Dataset::kChannel>(kSecondaryChannel);
|
||||
datasetInfo.Set<MeshCoP::Dataset::kPanId>(kLeader2PanId);
|
||||
{
|
||||
NetworkKey &networkKey = datasetInfo.Update<MeshCoP::Dataset::kNetworkKey>();
|
||||
memcpy(networkKey.m8, kNetworkKey, sizeof(networkKey));
|
||||
}
|
||||
{
|
||||
MeshCoP::Timestamp timestamp;
|
||||
timestamp.SetSeconds(kLeader2Timestamp);
|
||||
timestamp.SetTicks(0);
|
||||
datasetInfo.Set<MeshCoP::Dataset::kActiveTimestamp>(timestamp);
|
||||
}
|
||||
|
||||
datasetInfo.Set<MeshCoP::Dataset::kChannelMask>((1 << kPrimaryChannel) | (1 << kSecondaryChannel));
|
||||
|
||||
leader2.Get<MeshCoP::ActiveDatasetManager>().SaveLocal(datasetInfo);
|
||||
leader2.Get<ThreadNetif>().Up();
|
||||
SuccessOrQuit(leader2.Get<Mle::Mle>().Start());
|
||||
}
|
||||
|
||||
nexus.AdvanceTime(kFormNetworkTime);
|
||||
VerifyOrQuit(leader1.Get<Mle::Mle>().IsLeader());
|
||||
VerifyOrQuit(leader2.Get<Mle::Mle>().IsLeader());
|
||||
|
||||
dut.Join(leader1, Node::kAsMed);
|
||||
nexus.AdvanceTime(kJoinTime);
|
||||
VerifyOrQuit(dut.Get<Mle::Mle>().IsAttached());
|
||||
VerifyOrQuit(dut.Get<Mle::Mle>().GetParent().GetExtAddress() == leader1.Get<Mac::Mac>().GetExtAddress());
|
||||
|
||||
Log("---------------------------------------------------------------------------------------");
|
||||
Log("Step 2: Leader_1");
|
||||
|
||||
/**
|
||||
* Step 2: Leader_1
|
||||
* - Description: Harness silently powers-down Leader_1 and enables connectivity between the DUT and Leader_2
|
||||
* - Pass Criteria: N/A
|
||||
*/
|
||||
|
||||
leader1.Get<Mle::Mle>().Stop();
|
||||
leader1.Get<ThreadNetif>().Down();
|
||||
|
||||
leader2.AllowList(dut);
|
||||
dut.AllowList(leader2);
|
||||
|
||||
Log("---------------------------------------------------------------------------------------");
|
||||
Log("Step 3: DUT");
|
||||
|
||||
/**
|
||||
* Step 3: DUT
|
||||
* - Description: Automatically recognizes that its Parent is gone when it doesn’t receive responses to MLE Child
|
||||
* Update Requests
|
||||
* - Pass Criteria: N/A
|
||||
*/
|
||||
|
||||
nexus.AdvanceTime(kParentLossTime);
|
||||
|
||||
Log("---------------------------------------------------------------------------------------");
|
||||
Log("Step 4: DUT");
|
||||
|
||||
/**
|
||||
* Step 4: DUT
|
||||
* - Description: Automatically attempts to reattach to its current Thread Partition using the standard attaching
|
||||
* process
|
||||
* - Pass Criteria: The DUT MUST send a MLE Parent Request
|
||||
*/
|
||||
|
||||
Log("---------------------------------------------------------------------------------------");
|
||||
Log("Step 5: DUT");
|
||||
|
||||
/**
|
||||
* Step 5: DUT
|
||||
* - Description: The DUT does not receive a MLE Parent Response to its request
|
||||
* - Pass Criteria: N/A
|
||||
*/
|
||||
|
||||
nexus.AdvanceTime(kParentSelectionTime);
|
||||
|
||||
Log("---------------------------------------------------------------------------------------");
|
||||
Log("Step 6: DUT");
|
||||
|
||||
/**
|
||||
* Step 6: DUT
|
||||
* - Description: After failing to receive a MLE Parent Response to its request, the DUT automatically sends a MLE
|
||||
* Announce Message on the Secondary channel and waits on the Primary channel to hear any announcements.
|
||||
* - Pass Criteria: The DUT MUST send a MLE Announce Message, including the following TLVs:
|
||||
* - Channel TLV: ‘Primary’
|
||||
* - Active Timestamp TLV
|
||||
* - PAN ID TLV
|
||||
* - The Destination PAN ID in the IEEE 802.15.4 MAC header MUST be set to the Broadcast PAN ID (0xFFFF) and MUST
|
||||
* be secured using Key ID Mode 2.
|
||||
*/
|
||||
|
||||
nexus.AdvanceTime(kAnnounceTime);
|
||||
|
||||
Log("---------------------------------------------------------------------------------------");
|
||||
Log("Step 7: Leader_2");
|
||||
|
||||
/**
|
||||
* Step 7: Leader_2
|
||||
* - Description: Receives the MLE Announce from the DUT and automatically sends a MLE Announce on the Primary
|
||||
* channel because Leader_2 has a new Active Timestamp
|
||||
* - Pass Criteria: N/A
|
||||
*/
|
||||
|
||||
nexus.AdvanceTime(kAnnounceTime);
|
||||
|
||||
Log("---------------------------------------------------------------------------------------");
|
||||
Log("Step 8: DUT");
|
||||
|
||||
/**
|
||||
* Step 8: DUT
|
||||
* - Description: Receives the MLE Announce from Leader_2 and automatically attempts to attach on the Secondary
|
||||
* channel
|
||||
* - Pass Criteria: The DUT MUST attempt to attach on the Secondary channel, with the new PAN ID it received in the
|
||||
* MLE Announce message from Leader_2. The DUT MUST send a Parent Request on the Secondary channel
|
||||
*/
|
||||
|
||||
nexus.AdvanceTime(kAttachTime);
|
||||
|
||||
VerifyOrQuit(dut.Get<Mle::Mle>().IsAttached());
|
||||
VerifyOrQuit(dut.Get<Mle::Mle>().GetParent().GetExtAddress() == leader2.Get<Mac::Mac>().GetExtAddress());
|
||||
|
||||
Log("---------------------------------------------------------------------------------------");
|
||||
Log("Step 9: Leader_2");
|
||||
|
||||
/**
|
||||
* Step 9: Leader_2
|
||||
* - Description: Harness verifies connectivity by instructing Leader_2 to send an ICMP Echo Request to the DUT
|
||||
* - Pass Criteria: The DUT MUST respond with an ICMPv6 Echo Reply
|
||||
*/
|
||||
|
||||
nexus.SendAndVerifyEchoRequest(leader2, dut.Get<Mle::Mle>().GetMeshLocalEid(), 0, 64, kEchoTimeout);
|
||||
|
||||
nexus.SaveTestInfo("test_9_2_17.json");
|
||||
}
|
||||
|
||||
} // namespace Nexus
|
||||
} // namespace ot
|
||||
|
||||
int main(void)
|
||||
{
|
||||
ot::Nexus::Test9_2_17();
|
||||
printf("All tests passed\n");
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,171 @@
|
||||
#!/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):
|
||||
# 9.2.17 Orphaned End Devices
|
||||
#
|
||||
# 9.2.17.1 Topology
|
||||
# - Leader_1
|
||||
# - Leader_2
|
||||
# - ED_1 (DUT)
|
||||
#
|
||||
# 9.2.17.2 Purpose & Description
|
||||
# The purpose of this test case to validate end device functionality when its Parent is no longer available and
|
||||
# searches for a new Parent using MLE Announce messages.
|
||||
#
|
||||
# Spec Reference | V1.1 Section | V1.3.0 Section
|
||||
# ---------------------|--------------|---------------
|
||||
# Orphaned End Devices | 8.7.7 | 8.7.7
|
||||
|
||||
pkts = pv.pkts
|
||||
pv.summary.show()
|
||||
|
||||
LEADER_1 = pv.vars['LEADER_1']
|
||||
LEADER_2 = pv.vars['LEADER_2']
|
||||
DUT = pv.vars['DUT']
|
||||
|
||||
PRIMARY_CHANNEL = 11
|
||||
SECONDARY_CHANNEL = 12
|
||||
LEADER_2_PAN_ID = 0x2222
|
||||
BROADCAST_PAN_ID = 0xffff
|
||||
|
||||
# Step 1: All
|
||||
# - Description: Form the two topologies and ensure the DUT is attached to Leader_1
|
||||
# - Pass Criteria: Ensure topology is formed correctly. Verify that Leader_1 & Leader_2 are sending MLE
|
||||
# Advertisements on separate channels.
|
||||
print("Step 1: Verify that Leader_1 & Leader_2 are sending MLE Advertisements on separate channels.")
|
||||
pkts.filter_wpan_src64(LEADER_1).\
|
||||
filter_LLANMA().\
|
||||
filter_mle_cmd(consts.MLE_ADVERTISEMENT).\
|
||||
filter(lambda p: p.wpan_tap.ch_num == PRIMARY_CHANNEL).\
|
||||
must_next()
|
||||
pkts.filter_wpan_src64(LEADER_2).\
|
||||
filter_LLANMA().\
|
||||
filter_mle_cmd(consts.MLE_ADVERTISEMENT).\
|
||||
filter(lambda p: p.wpan_tap.ch_num == SECONDARY_CHANNEL).\
|
||||
must_next()
|
||||
|
||||
# Step 2: Leader_1
|
||||
# - Description: Harness silently powers-down Leader_1 and enables connectivity between the DUT and Leader_2
|
||||
# - Pass Criteria: N/A
|
||||
print("Step 2: Harness silently powers-down Leader_1 and enables connectivity between the DUT and Leader_2")
|
||||
|
||||
# Step 3: DUT
|
||||
# - Description: Automatically recognizes that its Parent is gone when it doesn’t receive responses to MLE Child
|
||||
# Update Requests
|
||||
# - Pass Criteria: N/A
|
||||
print("Step 3: DUT automatically recognizes that its Parent is gone")
|
||||
|
||||
# Step 4: DUT
|
||||
# - Description: Automatically attempts to reattach to its current Thread Partition using the standard attaching
|
||||
# process
|
||||
# - Pass Criteria: The DUT MUST send a MLE Parent Request
|
||||
print("Step 4: The DUT MUST send a MLE Parent Request")
|
||||
pkts.filter_wpan_src64(DUT).\
|
||||
filter_mle_cmd(consts.MLE_PARENT_REQUEST).\
|
||||
filter(lambda p: p.wpan_tap.ch_num == PRIMARY_CHANNEL).\
|
||||
must_next()
|
||||
|
||||
# Step 5: DUT
|
||||
# - Description: The DUT does not receive a MLE Parent Response to its request
|
||||
# - Pass Criteria: N/A
|
||||
print("Step 5: The DUT does not receive a MLE Parent Response to its request")
|
||||
|
||||
# Step 6: DUT
|
||||
# - Description: After failing to receive a MLE Parent Response to its request, the DUT automatically sends a MLE
|
||||
# Announce Message on the Secondary channel and waits on the Primary channel to hear any announcements.
|
||||
# - Pass Criteria: The DUT MUST send a MLE Announce Message, including the following TLVs:
|
||||
# - Channel TLV: ‘Primary’
|
||||
# - Active Timestamp TLV
|
||||
# - PAN ID TLV
|
||||
# - The Destination PAN ID in the IEEE 802.15.4 MAC header MUST be set to the Broadcast PAN ID (0xFFFF) and MUST
|
||||
# be secured using Key ID Mode 2.
|
||||
print("Step 6: The DUT MUST send a MLE Announce Message")
|
||||
pkts.filter_wpan_src64(DUT).\
|
||||
filter_mle_cmd(consts.MLE_ANNOUNCE).\
|
||||
filter(lambda p: p.wpan_tap.ch_num == SECONDARY_CHANNEL).\
|
||||
filter(lambda p: {
|
||||
consts.CHANNEL_TLV,
|
||||
consts.ACTIVE_TIMESTAMP_TLV,
|
||||
consts.PAN_ID_TLV
|
||||
} <= set(p.mle.tlv.type)).\
|
||||
filter(lambda p: p.mle.tlv.channel == PRIMARY_CHANNEL).\
|
||||
filter(lambda p: p.wpan.dst_pan == BROADCAST_PAN_ID).\
|
||||
filter(lambda p: p.wpan.aux_sec.key_id_mode == 0x2).\
|
||||
must_next()
|
||||
|
||||
# Step 7: Leader_2
|
||||
# - Description: Receives the MLE Announce from the DUT and automatically sends a MLE Announce on the Primary
|
||||
# channel because Leader_2 has a new Active Timestamp
|
||||
# - Pass Criteria: N/A
|
||||
print("Step 7: Leader_2 sends a MLE Announce on the Primary channel")
|
||||
pkts.filter_wpan_src64(LEADER_2).\
|
||||
filter_mle_cmd(consts.MLE_ANNOUNCE).\
|
||||
filter(lambda p: p.wpan_tap.ch_num == PRIMARY_CHANNEL).\
|
||||
must_next()
|
||||
|
||||
# Step 8: DUT
|
||||
# - Description: Receives the MLE Announce from Leader_2 and automatically attempts to attach on the Secondary
|
||||
# channel
|
||||
# - Pass Criteria: The DUT MUST attempt to attach on the Secondary channel, with the new PAN ID it received in the
|
||||
# MLE Announce message from Leader_2. The DUT MUST send a Parent Request on the Secondary channel
|
||||
print("Step 8: The DUT MUST send a Parent Request on the Secondary channel")
|
||||
pkts.filter_wpan_src64(DUT).\
|
||||
filter_mle_cmd(consts.MLE_PARENT_REQUEST).\
|
||||
filter(lambda p: p.wpan_tap.ch_num == SECONDARY_CHANNEL).\
|
||||
filter(lambda p: p.wpan.dst_pan == LEADER_2_PAN_ID).\
|
||||
must_next()
|
||||
|
||||
# Step 9: Leader_2
|
||||
# - Description: Harness verifies connectivity by instructing Leader_2 to send an ICMP Echo Request to the DUT
|
||||
# - Pass Criteria: The DUT MUST respond with an ICMPv6 Echo Reply
|
||||
print("Step 9: ICMPv6 Echo Request/Reply")
|
||||
_pkt = pkts.filter_ping_request().\
|
||||
filter_ipv6_src(pv.vars['LEADER_2_MLEID']).\
|
||||
filter_ipv6_dst(pv.vars['DUT_MLEID']).\
|
||||
must_next()
|
||||
pkts.filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier).\
|
||||
filter_ipv6_src(pv.vars['DUT_MLEID']).\
|
||||
filter_ipv6_dst(pv.vars['LEADER_2_MLEID']).\
|
||||
must_next()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
verify_utils.run_main(verify)
|
||||
Reference in New Issue
Block a user