[nexus] add 1_3_DIAG_TC_2 for Get Diagnostics - End Device (#12791)

This commit adds the Nexus test case 1_3_DIAG_TC_2 which verifies
that an End Device correctly reports its diagnostic information and
MLE counters via Network Diagnostic queries, as per the Thread 1.4
test specification.

The implementation includes:
- tests/nexus/test_1_3_DIAG_TC_2.cpp: Sets up a topology with a Leader,
  a Router, and a TD_1 (DUT) configured as a MED. It triggers Network
  Diagnostic Get queries from the Leader to the DUT for various TLVs
  including Max Child Timeout, EUI-64, Version, Vendor info, and MLE
  Counters.
- tests/nexus/verify_1_3_DIAG_TC_2.py: Performs automated verification
  of the captured traffic. It validates the presence and values of
  requested TLVs (Type 19, 23-28) and ensures that MLE Counters (Type
  34) reflect the expected role changes and tracking time.
- Integrated the new test into tests/nexus/CMakeLists.txt and
  tests/nexus/run_nexus_tests.sh.

The test ensures the correctness of Thread 1.4 End Device Diagnostic
and MLE Counter reporting, facilitating network health monitoring
and troubleshooting in a Thread network.
This commit is contained in:
Jonathan Hui
2026-03-30 14:24:45 -05:00
committed by GitHub
parent ba33b6bf13
commit 0883176d31
4 changed files with 584 additions and 0 deletions
+1
View File
@@ -280,6 +280,7 @@ ot_nexus_test(1_3_SRPC_TC_4 "cert;nexus")
ot_nexus_test(1_3_SRPC_TC_5 "cert;nexus")
ot_nexus_test(1_3_SRPC_TC_7 "cert;nexus")
ot_nexus_test(1_3_DIAG_TC_1 "cert;nexus")
ot_nexus_test(1_3_DIAG_TC_2 "cert;nexus")
# Misc tests
ot_nexus_test(border_admitter "core;nexus")
+1
View File
@@ -215,6 +215,7 @@ DEFAULT_TESTS=(
"1_3_SRPC_TC_5"
"1_3_SRPC_TC_7"
"1_3_DIAG_TC_1"
"1_3_DIAG_TC_2"
)
# Use provided arguments or the default test list
+267
View File
@@ -0,0 +1,267 @@
/*
* 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 "platform/nexus_core.hpp"
#include "platform/nexus_node.hpp"
#include "thread/network_diagnostic.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 = 15 * 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 diagnostic response to be received.
*/
static constexpr uint32_t kDiagResponseTime = 5 * 1000;
/**
* Time to wait in Step 4, in milliseconds.
*/
static constexpr uint32_t kWaitTime = 4 * 1000;
void TestDiagTc2(const char *aJsonFile)
{
/**
* 4.2. [1.4] [CERT] Get Diagnostics End Device
*
* 4.2.2. Topology
* - Leader_1
* - Router_1
* - TD_1 (DUT)
*
* Spec Reference | Section
* -----------------|---------
* Thread 1.4 | 4.2
*/
Core nexus;
Node &leader1 = nexus.CreateNode();
Node &router1 = nexus.CreateNode();
Node &td1 = nexus.CreateNode();
leader1.SetName("Leader_1");
router1.SetName("Router_1");
td1.SetName("TD_1");
nexus.AdvanceTime(0);
SuccessOrQuit(Instance::SetGlobalLogLevel(kLogLevelNote));
/**
* - Leader_1 and Router_1
* - Router_1 and TD_1
*/
leader1.AllowList(router1);
router1.AllowList(leader1);
router1.AllowList(td1);
td1.AllowList(router1);
Log("---------------------------------------------------------------------------------------");
Log("Step 1: Enable the devices in order. Leader configures its Network Data with an OMR prefix.");
/**
* Step 1
* - Device: Leader, Router_1
* - Description (DIAG-4.2): Enable the devices in order. The DUT is not yet activated. Leader
* configures its Network Data with an OMR prefix. Note: the OMR prefix can be added using an
* OT CLI command such as: "prefix add 2001:dead:beef:cafe::/64 paros med"
* - Pass Criteria:
* - Single Thread Network is formed with Leader and Router_1.
*/
leader1.Form();
nexus.AdvanceTime(kFormNetworkTime);
VerifyOrQuit(leader1.Get<Mle::Mle>().IsLeader());
router1.Join(leader1);
nexus.AdvanceTime(kAttachToRouterTime);
VerifyOrQuit(router1.Get<Mle::Mle>().IsRouter());
NetworkData::OnMeshPrefixConfig omrPrefixConfig;
SuccessOrQuit(omrPrefixConfig.GetPrefix().FromString("2001:dead:beef:cafe::/64"));
omrPrefixConfig.mPreferred = true;
omrPrefixConfig.mSlaac = true;
omrPrefixConfig.mDhcp = false;
omrPrefixConfig.mDefaultRoute = true;
omrPrefixConfig.mOnMesh = true;
omrPrefixConfig.mStable = true;
omrPrefixConfig.mPreference = NetworkData::kRoutePreferenceMedium;
SuccessOrQuit(leader1.Get<NetworkData::Local>().AddOnMeshPrefix(omrPrefixConfig));
leader1.Get<NetworkData::Notifier>().HandleServerDataUpdated();
nexus.AdvanceTime(30 * 1000); // Wait for network data propagation
Log("---------------------------------------------------------------------------------------");
Log("Step 1b: TD_1 (DUT) Enable.");
/**
* Step 1b
* - Device: TD_1 (DUT)
* - Description (DIAG-4.2): Enable.
* - Pass Criteria:
* - N/A
*/
td1.Join(router1, Node::kAsMed);
nexus.AdvanceTime(kAttachToRouterTime);
VerifyOrQuit(td1.Get<Mle::Mle>().IsChild());
Log("---------------------------------------------------------------------------------------");
Log("Step 2: Leader instructs device to send DIAG_GET.req to DUT's RLOC for Diagnostic TLV types.");
/**
* Step 2
* - Device: Leader
* - Description (DIAG-4.2): Harness instructs device to send DIAG_GET.req to DUT's RLOC for the
* following Diagnostic TLV types: Type 19: Max Child Timeout TLV, Type 23: EUI-64 TLV, Type
* 24: Version TLV, Type 25: Vendor Name TLV, Type 26: Vendor Model TLV, Type 27: Vendor SW
* Version TLV, Type 28: Thread Stack Version TLV
* - Pass Criteria:
* - N/A
*/
Ip6::Address td1Rloc;
td1Rloc.SetToRoutingLocator(leader1.Get<Mle::Mle>().GetMeshLocalPrefix(), td1.Get<Mle::Mle>().GetRloc16());
uint8_t tlvTypesStep2[] = {
NetworkDiagnostic::Tlv::kMaxChildTimeout,
NetworkDiagnostic::Tlv::kEui64,
NetworkDiagnostic::Tlv::kVersion,
NetworkDiagnostic::Tlv::kVendorName,
NetworkDiagnostic::Tlv::kVendorModel,
NetworkDiagnostic::Tlv::kVendorSwVersion,
NetworkDiagnostic::Tlv::kThreadStackVersion,
};
SuccessOrQuit(leader1.Get<NetworkDiagnostic::Client>().SendDiagnosticGet(td1Rloc, tlvTypesStep2,
sizeof(tlvTypesStep2), nullptr, nullptr));
Log("---------------------------------------------------------------------------------------");
Log("Step 3: TD_1 (DUT) Automatically responds either with 1. DIAG_GET.rsp or 2. CoAP response 4.04.");
/**
* Step 3
* - Device: TD_1 (DUT)
* - Description (DIAG-4.2): Automatically responds either with 1. DIAG_GET.rsp containing the
* requested Diagnostic TLVs, or a particular subset of those TLVs; 2. CoAP response 4.04 Not
* Found in case no diagnostics are supported at all.
* - Pass Criteria:
* - For case 1, the CoAP status code MUST be 2.04 Changed.
* - Each TLV (as requested in step 2) that is present in the response MUST be validated. Any
* number of TLVs MAY be present, from 0 to 7, depending on DUT's diagnostics support level.
* - The Max Child Timeout TLV (Type 19) is not expected to be present. However, if present it
* MUST be '0' (zero).
* - Value of EUI-64 TLV (Type 23) MUST be non-zero.
* - Value of Version TLV (Type 24) MUST be >= '5'.
* - Value of Vendor Name TLV (Type 25) MUST have length >= 1.
* - Value of Vendor Model TLV (Type 26) MUST have length >= 1.
* - Value of Vendor SW Version TLV (Type 27) MUST have length >= 5.
* - Value of Thread Stack Version TLV (Type 28) MUST have length >= 5.
* - For case 2, the CoAP status code is 4.04 and TLVs MUST NOT be present.
*/
nexus.AdvanceTime(kDiagResponseTime);
Log("---------------------------------------------------------------------------------------");
Log("Step 4: Harness waits for 4 seconds.");
/**
* Step 4
* - Device: N/A
* - Description (DIAG-4.2): Harness waits for 4 seconds. Note: this is done only to influence
* diagnostic Time fields that are verified in later steps.
* - Pass Criteria:
* - N/A
*/
nexus.AdvanceTime(kWaitTime);
Log("---------------------------------------------------------------------------------------");
Log("Step 4: Leader instructs device to send DIAG_GET.req unicast to DUT's RLOC for MLE Counters TLV.");
/**
* Step 4
* - Device: Leader
* - Description (DIAG-4.2): Harness instructs device to send DIAG_GET.req unicast to DUT's RLOC
* for the following Diagnostic TLV types: Type 34: MLE Counters TLV
* - Pass Criteria:
* - N/A
*/
uint8_t tlvTypesStep4[] = {NetworkDiagnostic::Tlv::kMleCounters};
SuccessOrQuit(leader1.Get<NetworkDiagnostic::Client>().SendDiagnosticGet(td1Rloc, tlvTypesStep4,
sizeof(tlvTypesStep4), nullptr, nullptr));
Log("---------------------------------------------------------------------------------------");
Log("Step 5: TD_1 (DUT) Automatically responds with DIAG_GET.rsp containing the requested Diagnostic TLVs.");
/**
* Step 5
* - Device: TD_1 (DUT)
* - Description (DIAG-4.2): Automatically responds with DIAG_GET.rsp containing the requested
* Diagnostic TLVs.
* - Pass Criteria:
* - The DUT must send DIAG_GET.rsp
* - The presence of each TLV (as requested in the previous step) MUST be validated.
* - In the MLE Counters TLV (Type 34):
* - Radio Disabled Counter MUST be '0'
* - Detached Role Counter MUST be '1'
* - Child Role Counter MUST be '1'
* - Router Role Counter MUST be '0'
* - Leader Role Counter MUST be '0'
* - Attach Attempts Counter MUST be >= 1
* - Partition ID Changes Counter MUST be '1'
* - New Parent Counter MUST be '0'
* - Total Tracking Time MUST be > 4000
* - Child Role Time MUST be >= 1
* - Router Role Time MUST be '0'
* - Leader Role Time MUST be '0'
*/
nexus.AdvanceTime(kDiagResponseTime);
nexus.SaveTestInfo(aJsonFile);
}
} // namespace Nexus
} // namespace ot
int main(int argc, char *argv[])
{
const char *jsonFile = (argc > 1) ? argv[argc - 1] : "test_1_3_DIAG_TC_2.json";
ot::Nexus::TestDiagTc2(jsonFile);
printf("All tests passed\n");
return 0;
}
+315
View File
@@ -0,0 +1,315 @@
#!/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
from pktverify.bytes import Bytes
# Diagnostic TLV Types
DG_EUI64_TLV = 23
DG_VERSION_TLV = 24
DG_VENDOR_NAME_TLV = 25
DG_VENDOR_MODEL_TLV = 26
DG_VENDOR_SW_VERSION_TLV = 27
DG_THREAD_STACK_VERSION_TLV = 28
DG_MLE_COUNTERS_TLV = 34
COAP_CODE_NOT_FOUND = 132
def read_uint16(b, offset):
return (b[offset] << 8) | b[offset + 1]
def read_uint32(b, offset):
return (b[offset] << 24) | (b[offset + 1] << 16) | (b[offset + 2] << 8) | b[offset + 3]
def read_uint64(b, offset):
val = 0
for i in range(8):
val = (val << 8) | b[offset + i]
return val
def get_diag_tlvs(p):
"""
Parses Thread Diagnostic TLVs from CoAP payload.
Returns a list of (type, value) tuples.
"""
payload = p.coap.payload
tlvs = []
offset = 0
while offset < len(payload):
t = payload[offset]
l = payload[offset + 1]
v = Bytes(payload[offset + 2:offset + 2 + l])
tlvs.append((t, v))
offset += 2 + l
return tlvs
def get_tlv_value(tlvs, tlv_type):
"""
Returns the value of the first TLV of a given type.
"""
for t, v in tlvs:
if t == tlv_type:
return v
return None
def verify(pv):
"""
4.2. [1.4] [CERT] Get Diagnostics End Device
4.2.2. Topology
- Leader_1
- Router_1
- TD_1 (DUT)
Spec Reference | Section
---------------|--------
Thread 1.4 | 4.2
"""
pkts = pv.pkts
pv.summary.show()
Leader_1_RLOC = pv.vars['Leader_1_RLOC']
# Step 1
# Device: Leader, Router_1
# Description (DIAG-4.2): Enable the devices in order. The DUT is not yet activated. Leader
# configures its Network Data with an OMR prefix. Note: the OMR prefix can be added using
# an OT CLI command such as: "prefix add 2001:dead:beef:cafe::/64 paros med"
# Pass Criteria:
# - Single Thread Network is formed with Leader and Router_1.
print("Step 1: Single Thread Network is formed with Leader and Router_1.")
# Step 1b
# Device: TD_1 (DUT)
# Description (DIAG-4.2): Enable.
# Pass Criteria:
# - N/A
print("Step 1b: TD_1 (DUT) Enable.")
# Step 2
# Device: Leader
# Description (DIAG-4.2): Harness instructs device to send DIAG_GET.req to DUT's RLOC for the
# following Diagnostic TLV types: Type 19: Max Child Timeout TLV, Type 23: EUI-64 TLV, Type
# 24: Version TLV, Type 25: Vendor Name TLV, Type 26: Vendor Model TLV, Type 27: Vendor SW
# Version TLV, Type 28: Thread Stack Version TLV
# Pass Criteria:
# - N/A
print("Step 2: Leader sends DIAG_GET.req to DUT's RLOC.")
# Step 3
# Device: TD_1 (DUT)
# Description (DIAG-4.2): Automatically responds either with 1. DIAG_GET.rsp containing the
# requested Diagnostic TLVs, or a particular subset of those TLVs; 2. CoAP response 4.04 Not
# Found in case no diagnostics are supported at all.
# Pass Criteria:
# - For case 1, the CoAP status code MUST be 2.04 Changed.
# - Each TLV (as requested in step 2) that is present in the response MUST be validated. Any
# number of TLVs MAY be present, from 0 to 7, depending on DUT's diagnostics support level.
# - The Max Child Timeout TLV (Type 19) is not expected to be present. However, if present it
# MUST be '0' (zero).
# - Value of EUI-64 TLV (Type 23) MUST be non-zero.
# - Value of Version TLV (Type 24) MUST be >= '5'.
# - Value of Vendor Name TLV (Type 25) MUST have length >= 1.
# - Value of Vendor Model TLV (Type 26) MUST have length >= 1.
# - Value of Vendor SW Version TLV (Type 27) MUST have length >= 5.
# - Value of Thread Stack Version TLV (Type 28) MUST have length >= 5.
# - For case 2, the CoAP status code is 4.04 and TLVs MUST NOT be present.
print("Step 3: TD_1 (DUT) responds either with 1. DIAG_GET.rsp or 2. CoAP response 4.04.")
def check_step3(p):
if p.coap.code == COAP_CODE_NOT_FOUND:
return len(p.coap.payload) == 0
if p.coap.code != consts.COAP_CODE_ACK:
return False
tlvs = get_diag_tlvs(p)
types = {t for t, v in tlvs}
# Case 1 validation
# Each TLV that is present in the response MUST be validated.
if consts.DG_MAX_CHILD_TIMEOUT_TLV in types:
val = get_tlv_value(tlvs, consts.DG_MAX_CHILD_TIMEOUT_TLV)
if read_uint32(val, 0) != 0:
return False
if DG_EUI64_TLV in types:
val = get_tlv_value(tlvs, DG_EUI64_TLV)
if read_uint64(val, 0) == 0:
return False
if DG_VERSION_TLV in types:
val = get_tlv_value(tlvs, DG_VERSION_TLV)
if read_uint16(val, 0) < 5:
return False
if DG_VENDOR_NAME_TLV in types:
val = get_tlv_value(tlvs, DG_VENDOR_NAME_TLV)
if len(val) < 1:
return False
if DG_VENDOR_MODEL_TLV in types:
val = get_tlv_value(tlvs, DG_VENDOR_MODEL_TLV)
if len(val) < 1:
return False
if DG_VENDOR_SW_VERSION_TLV in types:
val = get_tlv_value(tlvs, DG_VENDOR_SW_VERSION_TLV)
if len(val) < 5:
return False
if DG_THREAD_STACK_VERSION_TLV in types:
val = get_tlv_value(tlvs, DG_THREAD_STACK_VERSION_TLV)
if len(val) < 5:
return False
return True
pkts.filter_ipv6_dst(Leader_1_RLOC).\
filter(lambda p: (
p.coap.code in (consts.COAP_CODE_ACK, COAP_CODE_NOT_FOUND) and
p.coap.opt.uri_path_recon == consts.DIAG_GET_URI
)).\
filter(lambda p: (
check_step3(p)
)).\
must_next()
# Step 4
# Device: N/A
# Description (DIAG-4.2): Harness waits for 4 seconds. Note: this is done only to influence
# diagnostic Time fields that are verified in later steps.
# Pass Criteria:
# - N/A
print("Step 4: Harness waits for 4 seconds.")
# Step 4
# Device: Leader
# Description (DIAG-4.2): Harness instructs device to send DIAG_GET.req unicast to DUT's RLOC
# for the following Diagnostic TLV types: Type 34: MLE Counters TLV
# Pass Criteria:
# - N/A
print("Step 4: Leader sends DIAG_GET.req unicast to DUT's RLOC for MLE Counters TLV.")
# Step 5
# Device: TD_1 (DUT)
# Description (DIAG-4.2): Automatically responds with DIAG_GET.rsp containing the requested
# Diagnostic TLVs.
# Pass Criteria:
# - The DUT must send DIAG_GET.rsp
# - The presence of each TLV (as requested in the previous step) MUST be validated.
# - In the MLE Counters TLV (Type 34):
# - Radio Disabled Counter MUST be '0'
# - Detached Role Counter MUST be '1'
# - Child Role Counter MUST be '1'
# - Router Role Counter MUST be '0'
# - Leader Role Counter MUST be '0'
# - Attach Attempts Counter MUST be >= 1
# - Partition ID Changes Counter MUST be '1'
# - New Parent Counter MUST be '0'
# - Total Tracking Time MUST be > 4000
# - Child Role Time MUST be >= 1
# - Router Role Time MUST be '0'
# - Leader Role Time MUST be '0'
print("Step 5: TD_1 (DUT) responds with DIAG_GET.rsp.")
def check_step5(p):
tlvs = get_diag_tlvs(p)
types = {t for t, v in tlvs}
if DG_MLE_COUNTERS_TLV not in types:
return False
val = get_tlv_value(tlvs, DG_MLE_COUNTERS_TLV)
if len(val) < 66:
return False
# Radio Disabled Counter MUST be '0'
if read_uint16(val, 0) != 0:
return False
# Detached Role Counter MUST be '1'
if read_uint16(val, 2) != 1:
return False
# Child Role Counter MUST be '1'
if read_uint16(val, 4) != 1:
return False
# Router Role Counter MUST be '0'
if read_uint16(val, 6) != 0:
return False
# Leader Role Counter MUST be '0'
if read_uint16(val, 8) != 0:
return False
# Attach Attempts Counter MUST be >= 1
if read_uint16(val, 10) < 1:
return False
# Partition ID Changes Counter MUST be '1'
if read_uint16(val, 12) != 1:
return False
# New Parent Counter MUST be '0'
if read_uint16(val, 16) != 0:
return False
# Total Tracking Time MUST be > 4000
if read_uint64(val, 18) <= 4000:
return False
# Child Role Time MUST be >= 1
if read_uint64(val, 42) < 1:
return False
# Router Role Time MUST be '0'
if read_uint64(val, 50) != 0:
return False
# Leader Role Time MUST be '0'
if read_uint64(val, 58) != 0:
return False
return True
pkts.filter_ipv6_dst(Leader_1_RLOC).\
filter_coap_ack(consts.DIAG_GET_URI).\
filter(lambda p: (
check_step5(p)
)).\
must_next()
if __name__ == '__main__':
verify_utils.run_main(verify)