[net-diag] define Child, Neighbor, and Child IPv6 Address List TLVs (#8866)

This commit contains multiple changes to Network Diagnostics
modules.

It adds new TLVs: Child TLV, Child IPv6 Address List TLV, Router
Neighbor TLV and MLE counters TLV.

Child TLV contains information about a child entry including RLOC16,
extended MAC address, mode (rx-on-idle, FTD/MTD, full netdata,
CSL-sync), timeout, age, supervision interval, CSL period and
timeout, and link quality info such as RSS (last and average) and
frame/message error rates. Neighbor TLV provides similar info for a
router neighbor. The Child IPv6 Address List TLV allows to query a
parent to get the list of IPv6 addresses registered by its MTD
children.

The new Child and Neighbor TLVs can be requested in Network Diagnostic
Get Query "d/dq" message to a router (unicast) or multiple routers
(multicast). The router responds with one or more Network Diagnostic
Get Answer "d/da" messages.

We allow multiple Answer messages to be sent in response to a Query.
This is to support the case where a router has many children, and we
want to avoid sending a large message that contains all of the TLVs
for all of the children. Instead, we can send a sequence of Answer
messages, each of which contains a subset of the TLVs.

Each Answer message includes an Answer TLV that indicates the index of
the message in the sequence. The first Answer message has an index of
0, the second has an index of 1, and so on. The Answer TLV also
indicates whether the message is the last one in the sequence, or if
there are more Answer messages to come. Answer messages are sent in
sequence, and the next one is not sent until we receive a successful
CoAP ACK/response for the previous one.

This commit adds a Query ID TLV (with a 16-bit identifier as it
value) that can be optionally included in a Query message. The Query
ID is echoed back in all Answer messages associated with the same
Query message. This allows a node that sends multiple Queries to
distinguish between the received Answers.

This commit updates `MeshDiag` to use the newly added TLVs
to query the child table or children IPv6 addresses of a router.
New public OpenThread APIs under `otMeshDiag` are added for this,
along with CLI commands and their documentation. A test-case is added
to validate the newly added mechanism.
This commit is contained in:
Abtin Keshavarzian
2023-07-10 11:35:27 -07:00
committed by GitHub
parent 9ed5c5e72f
commit 1839f15417
21 changed files with 2524 additions and 135 deletions
@@ -250,7 +250,7 @@ class Cert_5_7_02_CoapDiagCommands(thread_cert.TestCase):
pkts.filter_wpan_src64(LEADER).\
filter_ipv6_dst(DUT_RLOC).\
filter_coap_request(DIAG_GET_URI).\
filter(lambda p: dut_payload_tlvs == set(p.thread_diagnostic.tlv.type)).\
filter(lambda p: dut_payload_tlvs <= set(p.thread_diagnostic.tlv.type)).\
must_next()
dut_payload_tlvs.remove(DG_TYPE_LIST_TLV)
dut_payload_tlvs.remove(DG_ROUTE64_TLV)
@@ -277,7 +277,7 @@ class Cert_5_7_02_CoapDiagCommands(thread_cert.TestCase):
filter(lambda p: {
DG_TYPE_LIST_TLV,
DG_MAC_COUNTERS_TLV
} == set(p.thread_diagnostic.tlv.type)
} <= set(p.thread_diagnostic.tlv.type)
).\
must_next()
pkts.filter_wpan_src64(DUT).\
@@ -285,7 +285,7 @@ class Cert_5_7_02_CoapDiagCommands(thread_cert.TestCase):
filter_coap_ack(DIAG_GET_URI).\
filter(lambda p: {
DG_MAC_COUNTERS_TLV
} == set(p.thread_diagnostic.tlv.type)
} <= set(p.thread_diagnostic.tlv.type)
).\
must_next()
@@ -304,7 +304,7 @@ class Cert_5_7_02_CoapDiagCommands(thread_cert.TestCase):
DG_TYPE_LIST_TLV,
DG_TIMEOUT_TLV,
DG_CHILD_TABLE_TLV
} == set(p.thread_diagnostic.tlv.type)
} <= set(p.thread_diagnostic.tlv.type)
).\
must_next()
pkts.filter_wpan_src64(DUT).\
@@ -327,7 +327,7 @@ class Cert_5_7_02_CoapDiagCommands(thread_cert.TestCase):
DG_TYPE_LIST_TLV,
DG_BATTERY_LEVEL_TLV,
DG_SUPPLY_VOLTAGE_TLV
} == set(p.thread_diagnostic.tlv.type)
} <= set(p.thread_diagnostic.tlv.type)
).\
must_next()
pkts.filter_wpan_src64(DUT).\
@@ -347,7 +347,7 @@ class Cert_5_7_02_CoapDiagCommands(thread_cert.TestCase):
filter(lambda p: {
DG_TYPE_LIST_TLV,
DG_MAC_COUNTERS_TLV
} == set(p.thread_diagnostic.tlv.type)
} <= set(p.thread_diagnostic.tlv.type)
).\
must_next()
pkts.filter_wpan_src64(DUT).\
@@ -370,7 +370,7 @@ class Cert_5_7_02_CoapDiagCommands(thread_cert.TestCase):
filter(lambda p: {
DG_TYPE_LIST_TLV,
DG_MAC_COUNTERS_TLV
} == set(p.thread_diagnostic.tlv.type)
} <= set(p.thread_diagnostic.tlv.type)
).\
must_next()
pkts.filter_wpan_src64(DUT).\
@@ -378,7 +378,7 @@ class Cert_5_7_02_CoapDiagCommands(thread_cert.TestCase):
filter_coap_ack(DIAG_GET_URI).\
filter(lambda p: {
DG_MAC_COUNTERS_TLV
} == set(p.thread_diagnostic.tlv.type)
} <= set(p.thread_diagnostic.tlv.type)
).\
must_next()
@@ -401,7 +401,7 @@ class Cert_5_7_02_CoapDiagCommands(thread_cert.TestCase):
pkts.filter_wpan_src64(LEADER).\
filter_ipv6_dst(REALM_LOCAL_All_THREAD_NODES_MULTICAST_ADDRESS).\
filter_coap_request(DIAG_GET_QRY_URI).\
filter(lambda p: dut_payload_tlvs == set(p.thread_diagnostic.tlv.type)).\
filter(lambda p: dut_payload_tlvs <= set(p.thread_diagnostic.tlv.type)).\
must_next()
dut_payload_tlvs.remove(DG_TYPE_LIST_TLV)
@@ -189,7 +189,7 @@ class Cert_5_7_03_CoapDiagCommands_Base(thread_cert.TestCase):
}
if self.TOPOLOGY[ROUTER1]['name'] == 'DUT':
dut_payload_tlvs.update({DG_CONNECTIVITY_TLV, DG_ROUTE64_TLV, DG_CHILD_TABLE_TLV})
_qr_pkt.must_verify(lambda p: dut_payload_tlvs == set(p.thread_diagnostic.tlv.type))
_qr_pkt.must_verify(lambda p: dut_payload_tlvs <= set(p.thread_diagnostic.tlv.type))
# Step 3: The DUT automatically responds with a DIAG_GET.ans response
# MUST contain the requested diagnostic TLVs:
@@ -208,7 +208,7 @@ class Cert_5_7_03_CoapDiagCommands_Base(thread_cert.TestCase):
filter_ipv6_dst(LEADER_RLOC).\
filter_coap_request(DIAG_GET_ANS_URI).\
filter(lambda p:
dut_payload_tlvs == set(p.thread_diagnostic.tlv.type) and\
dut_payload_tlvs <= set(p.thread_diagnostic.tlv.type) and\
{str(p.wpan.src64), colon_hex(dut_addr16, 2), '0f'}
< set(p.thread_diagnostic.tlv.general)
).\
@@ -221,7 +221,7 @@ class Cert_5_7_03_CoapDiagCommands_Base(thread_cert.TestCase):
filter_ipv6_dst(REALM_LOCAL_All_THREAD_NODES_MULTICAST_ADDRESS).\
filter_coap_request(DIAG_GET_QRY_URI).\
filter(lambda p:
dut_payload_tlvs == set(p.thread_diagnostic.tlv.type)
dut_payload_tlvs <= set(p.thread_diagnostic.tlv.type)
).\
must_next()
@@ -240,7 +240,7 @@ class Cert_5_7_03_CoapDiagCommands_Base(thread_cert.TestCase):
filter_ipv6_dst(LEADER_RLOC).\
filter_coap_request(DIAG_GET_ANS_URI).\
filter(lambda p:
dut_payload_tlvs == set(p.thread_diagnostic.tlv.type) and\
dut_payload_tlvs <= set(p.thread_diagnostic.tlv.type) and\
{str(p.wpan.src64), colon_hex(dut_addr16, 2), '0f'}
< set(p.thread_diagnostic.tlv.general)
).\