mirror of
https://github.com/espressif/openthread.git
synced 2026-08-08 11:47:46 +00:00
[cli] add the sync option to the linkmetrics cli commands (#10518)
The cli command `linkmetrics` only provides an asynchronous output method. It is difficult for scripts to call the `ot-ctl` to capture the results of asynchronous output. This commit replaces the command `linkmetrics mgmt` and `linkmetrics query` with commands `linkmetrics config` and `linkmetrics request`. Both the commands `linkmetrics config` and `linkmetrics request` are set to the `sync` mode by default, and an option `async` is added to these commands to support `async` mode.
This commit is contained in:
@@ -3255,14 +3255,14 @@ class NodeImpl:
|
||||
|
||||
return router_table
|
||||
|
||||
def link_metrics_query_single_probe(self, dst_addr: str, linkmetrics_flags: str, block: str = ""):
|
||||
cmd = 'linkmetrics query %s single %s %s' % (dst_addr, linkmetrics_flags, block)
|
||||
def link_metrics_request_single_probe(self, dst_addr: str, linkmetrics_flags: str, mode: str = ''):
|
||||
cmd = 'linkmetrics request %s %s single %s' % (mode, dst_addr, linkmetrics_flags)
|
||||
self.send_command(cmd)
|
||||
self.simulator.go(5)
|
||||
return self._parse_linkmetrics_query_result(self._expect_command_output())
|
||||
|
||||
def link_metrics_query_forward_tracking_series(self, dst_addr: str, series_id: int, block: str = ""):
|
||||
cmd = 'linkmetrics query %s forward %d %s' % (dst_addr, series_id, block)
|
||||
def link_metrics_request_forward_tracking_series(self, dst_addr: str, series_id: int, mode: str = ''):
|
||||
cmd = 'linkmetrics request %s %s forward %d' % (mode, dst_addr, series_id)
|
||||
self.send_command(cmd)
|
||||
self.simulator.go(5)
|
||||
return self._parse_linkmetrics_query_result(self._expect_command_output())
|
||||
@@ -3288,12 +3288,13 @@ class NodeImpl:
|
||||
result['Status'] = line[29:]
|
||||
return result
|
||||
|
||||
def link_metrics_mgmt_req_enhanced_ack_based_probing(self,
|
||||
dst_addr: str,
|
||||
enable: bool,
|
||||
metrics_flags: str,
|
||||
ext_flags=''):
|
||||
cmd = "linkmetrics mgmt %s enhanced-ack" % (dst_addr)
|
||||
def link_metrics_config_req_enhanced_ack_based_probing(self,
|
||||
dst_addr: str,
|
||||
enable: bool,
|
||||
metrics_flags: str,
|
||||
ext_flags='',
|
||||
mode: str = ''):
|
||||
cmd = "linkmetrics config %s %s enhanced-ack" % (mode, dst_addr)
|
||||
if enable:
|
||||
cmd = cmd + (" register %s %s" % (metrics_flags, ext_flags))
|
||||
else:
|
||||
@@ -3301,9 +3302,13 @@ class NodeImpl:
|
||||
self.send_command(cmd)
|
||||
self._expect_done()
|
||||
|
||||
def link_metrics_mgmt_req_forward_tracking_series(self, dst_addr: str, series_id: int, series_flags: str,
|
||||
metrics_flags: str):
|
||||
cmd = "linkmetrics mgmt %s forward %d %s %s" % (dst_addr, series_id, series_flags, metrics_flags)
|
||||
def link_metrics_config_req_forward_tracking_series(self,
|
||||
dst_addr: str,
|
||||
series_id: int,
|
||||
series_flags: str,
|
||||
metrics_flags: str,
|
||||
mode: str = ''):
|
||||
cmd = "linkmetrics config %s %s forward %d %s %s" % (mode, dst_addr, series_id, series_flags, metrics_flags)
|
||||
self.send_command(cmd)
|
||||
self._expect_done()
|
||||
|
||||
|
||||
+9
-5
@@ -99,7 +99,7 @@ class LowPower_7_1_01(thread_cert.TestCase):
|
||||
# ---- L = 0
|
||||
# ---- Type/Average Enum = 1 (Exponential Moving Avg)
|
||||
# ---- Metrics Enum = 2 (Link Margin)
|
||||
self.nodes[SED_1].link_metrics_mgmt_req_enhanced_ack_based_probing(leader_addr, True, 'm')
|
||||
self.nodes[SED_1].link_metrics_config_req_enhanced_ack_based_probing(leader_addr, True, 'm', mode='async')
|
||||
self.simulator.go(5)
|
||||
|
||||
# Step 6 - SSED_1 enables IEEE 802.15.4-2015 Enhanced ACK based Probing by sending a Link Metrics Management
|
||||
@@ -115,7 +115,7 @@ class LowPower_7_1_01(thread_cert.TestCase):
|
||||
# ---- Type/Average Enum = 1 (Exponential Moving Avg)
|
||||
# ---- Metrics Enum = 2 (Link Margin)
|
||||
# ---- Metrics Enum = 3 (RSSI)
|
||||
self.nodes[SSED_1].link_metrics_mgmt_req_enhanced_ack_based_probing(leader_addr, True, 'mr')
|
||||
self.nodes[SSED_1].link_metrics_config_req_enhanced_ack_based_probing(leader_addr, True, 'mr', mode='async')
|
||||
self.simulator.go(5)
|
||||
|
||||
# Step 8 - SSED_1 sends an MLE Data Message with setting Frame Version subfield within the MAC header of the
|
||||
@@ -131,7 +131,7 @@ class LowPower_7_1_01(thread_cert.TestCase):
|
||||
# Step 12 - SSED_1 clears its Enhanced ACK link metrics configuration by # sending a Link Metrics Management
|
||||
# Request to the DUT
|
||||
# Enh-ACK Flags = 0 (clear enhanced ACK link metric config)
|
||||
self.nodes[SSED_1].link_metrics_mgmt_req_enhanced_ack_based_probing(leader_addr, False, '')
|
||||
self.nodes[SSED_1].link_metrics_config_req_enhanced_ack_based_probing(leader_addr, False, '', mode='async')
|
||||
self.simulator.go(5)
|
||||
|
||||
# Step 14 - SSED_1 Sends a MLE Data Message with setting Frame Version subfield within the MAC header of the
|
||||
@@ -154,7 +154,7 @@ class LowPower_7_1_01(thread_cert.TestCase):
|
||||
# ---- Metrics Enum = 1 (Layer 2 LQI)
|
||||
# ---- Metrics Enum = 2 (Link Margin)
|
||||
# ---- Metrics Enum = 3 (RSSI)
|
||||
self.nodes[SSED_1].link_metrics_mgmt_req_enhanced_ack_based_probing(leader_addr, True, 'qmr')
|
||||
self.nodes[SSED_1].link_metrics_config_req_enhanced_ack_based_probing(leader_addr, True, 'qmr', mode='async')
|
||||
self.simulator.go(5)
|
||||
|
||||
# Step 18 - This step verifies that Enhanced ACKs cannot be enabled while requesting a reserved Type/Average
|
||||
@@ -168,7 +168,11 @@ class LowPower_7_1_01(thread_cert.TestCase):
|
||||
# ---- L = 0
|
||||
# ---- Type/Average Enum = 2 (Reserved)
|
||||
# ---- Metrics Enum = 2 (Link Margin)
|
||||
self.nodes[SSED_1].link_metrics_mgmt_req_enhanced_ack_based_probing(leader_addr, True, 'm', 'r')
|
||||
self.nodes[SSED_1].link_metrics_config_req_enhanced_ack_based_probing(leader_addr,
|
||||
True,
|
||||
'm',
|
||||
'r',
|
||||
mode='async')
|
||||
self.simulator.go(5)
|
||||
|
||||
def verify(self, pv):
|
||||
|
||||
+5
-5
@@ -108,7 +108,7 @@ class LowPower_7_1_02_SingleProbeLinkMetricsWithoutEnhancedAck(thread_cert.TestC
|
||||
# In this step, SED_1 should set its TxPower to 'High'. In simulation, this will be implemented by
|
||||
# setting Macfilter on the Rx side (Leader).
|
||||
self.nodes[LEADER].add_allowlist(sed_extaddr, -30)
|
||||
res = self.nodes[SED_1].link_metrics_query_single_probe(leader_addr, 'r', 'block')
|
||||
res = self.nodes[SED_1].link_metrics_request_single_probe(leader_addr, 'r')
|
||||
rss_1 = int(res['RSSI'])
|
||||
self.simulator.go(5)
|
||||
|
||||
@@ -125,7 +125,7 @@ class LowPower_7_1_02_SingleProbeLinkMetricsWithoutEnhancedAck(thread_cert.TestC
|
||||
#
|
||||
# In this step, SED_1 should set its TxPower to 'Low'.
|
||||
self.nodes[LEADER].add_allowlist(sed_extaddr, -95)
|
||||
res = self.nodes[SED_1].link_metrics_query_single_probe(leader_addr, 'r', 'block')
|
||||
res = self.nodes[SED_1].link_metrics_request_single_probe(leader_addr, 'r')
|
||||
rss_2 = int(res['RSSI'])
|
||||
self.simulator.go(5)
|
||||
|
||||
@@ -142,7 +142,7 @@ class LowPower_7_1_02_SingleProbeLinkMetricsWithoutEnhancedAck(thread_cert.TestC
|
||||
# --- Metric Type ID Flags
|
||||
# ---- Type / Average Enum = 1 (Exponential Moving Avg)
|
||||
# ---- Metric Enum = 1 (Layer 2 LQI)
|
||||
self.nodes[SSED_1].link_metrics_query_single_probe(leader_addr, 'q', 'block')
|
||||
self.nodes[SSED_1].link_metrics_request_single_probe(leader_addr, 'q')
|
||||
self.simulator.go(5)
|
||||
|
||||
# Step 11 - SSED_1 sends a Single Probe Link Metric for Link Margin using MLE Data Request
|
||||
@@ -155,7 +155,7 @@ class LowPower_7_1_02_SingleProbeLinkMetricsWithoutEnhancedAck(thread_cert.TestC
|
||||
# --- Metric Type ID Flags
|
||||
# ---- Type / Average Enum = 1 (Exponential Moving Avg)
|
||||
# ---- Metric Enum = 2 (Link Margin)
|
||||
self.nodes[SSED_1].link_metrics_query_single_probe(leader_addr, 'm', 'block')
|
||||
self.nodes[SSED_1].link_metrics_request_single_probe(leader_addr, 'm')
|
||||
self.simulator.go(5)
|
||||
|
||||
# Step 13 - SSED_1 sends a Single Probe Link Metric using MLE Data Request
|
||||
@@ -170,7 +170,7 @@ class LowPower_7_1_02_SingleProbeLinkMetricsWithoutEnhancedAck(thread_cert.TestC
|
||||
# ---- Metric Enum = 1 (Layer 2 LQI)
|
||||
# ---- Metric Enum = 2 (Link Margin)
|
||||
# ---- Metric Enum = 3 (RSSI)
|
||||
self.nodes[SSED_1].link_metrics_query_single_probe(leader_addr, 'qmr', 'block')
|
||||
self.nodes[SSED_1].link_metrics_request_single_probe(leader_addr, 'qmr')
|
||||
self.simulator.go(5)
|
||||
|
||||
def verify(self, pv):
|
||||
|
||||
@@ -103,7 +103,7 @@ class LowPower_7_2_01_ForwardTrackingSeries(thread_cert.TestCase):
|
||||
# -- L = 1
|
||||
# -- Type/Average Enum = 0 (count)
|
||||
# -- Metrics Enum = 0 (count)
|
||||
self.nodes[SED_1].link_metrics_mgmt_req_forward_tracking_series(leader_addr, SERIES_ID, 'r', 'p')
|
||||
self.nodes[SED_1].link_metrics_config_req_forward_tracking_series(leader_addr, SERIES_ID, 'r', 'p', 'async')
|
||||
|
||||
self.simulator.go(5)
|
||||
|
||||
@@ -111,7 +111,7 @@ class LowPower_7_2_01_ForwardTrackingSeries(thread_cert.TestCase):
|
||||
self.simulator.go(30)
|
||||
|
||||
# Step 7 - SED_1 sends an MLE Data Request to retrieve aggregated Forward Series Results
|
||||
result = self.nodes[SED_1].link_metrics_query_forward_tracking_series(leader_addr, SERIES_ID, 'block')
|
||||
result = self.nodes[SED_1].link_metrics_request_forward_tracking_series(leader_addr, SERIES_ID)
|
||||
self.assertIn("PDU Counter", result)
|
||||
|
||||
#self.simulator.go(5)
|
||||
@@ -120,7 +120,7 @@ class LowPower_7_2_01_ForwardTrackingSeries(thread_cert.TestCase):
|
||||
# Forward Series Flags = 0x00:
|
||||
# - Bits 0-7 = 0
|
||||
# Concatenation of Link Metric Type ID Flags = NULL:
|
||||
self.nodes[SED_1].link_metrics_mgmt_req_forward_tracking_series(leader_addr, SERIES_ID, 'X', '')
|
||||
self.nodes[SED_1].link_metrics_config_req_forward_tracking_series(leader_addr, SERIES_ID, 'X', '', 'async')
|
||||
|
||||
self.simulator.go(5)
|
||||
|
||||
@@ -134,7 +134,7 @@ class LowPower_7_2_01_ForwardTrackingSeries(thread_cert.TestCase):
|
||||
# -- L = 0
|
||||
# -- Type/Average Enum = 1 (Exponential Moving Average)
|
||||
# -- Metrics Enum = 2 (Link Margin)
|
||||
self.nodes[SSED_1].link_metrics_mgmt_req_forward_tracking_series(leader_addr, SERIES_ID_2, 'd', 'm')
|
||||
self.nodes[SSED_1].link_metrics_config_req_forward_tracking_series(leader_addr, SERIES_ID_2, 'd', 'm', 'async')
|
||||
|
||||
self.simulator.go(5)
|
||||
|
||||
@@ -145,19 +145,19 @@ class LowPower_7_2_01_ForwardTrackingSeries(thread_cert.TestCase):
|
||||
self.simulator.go(1)
|
||||
|
||||
# Step 19 - SSED_1 sends an MLE Data Request to retrieve aggregated Forward Series Results
|
||||
result = self.nodes[SSED_1].link_metrics_query_forward_tracking_series(leader_addr, SERIES_ID_2, 'block')
|
||||
result = self.nodes[SSED_1].link_metrics_request_forward_tracking_series(leader_addr, SERIES_ID_2)
|
||||
self.assertIn("Margin", result)
|
||||
|
||||
# Step 21 - SSED_1 clears the Forward Series Link Metrics
|
||||
# Forward Series Flags = 0x00:
|
||||
# - Bits 0-7 = 0
|
||||
# Concatenation of Link Metric Type ID Flags = NULL
|
||||
self.nodes[SSED_1].link_metrics_mgmt_req_forward_tracking_series(leader_addr, SERIES_ID_2, 'X', '')
|
||||
self.nodes[SSED_1].link_metrics_config_req_forward_tracking_series(leader_addr, SERIES_ID_2, 'X', '', 'async')
|
||||
|
||||
self.simulator.go(5)
|
||||
|
||||
# Step 23 - SSED_1 sends an MLE Data Request to retrieve aggregated Forward Series Results
|
||||
result = self.nodes[SSED_1].link_metrics_query_forward_tracking_series(leader_addr, SERIES_ID_2, 'block')
|
||||
result = self.nodes[SSED_1].link_metrics_request_forward_tracking_series(leader_addr, SERIES_ID_2)
|
||||
self.assertIn('Status', result)
|
||||
self.assertEqual(result['Status'], 'Series ID not recognized')
|
||||
|
||||
|
||||
@@ -76,38 +76,39 @@ class LowPower_test_ForwardTrackingSeries(thread_cert.TestCase):
|
||||
# 1. Child configures a Forward Tracking Series successfully.
|
||||
# The Series tracks the count of MAC Data Request.
|
||||
# Child should get a response with status 0 (SUCCESS).
|
||||
self.nodes[CHILD].link_metrics_mgmt_req_forward_tracking_series(leader_addr, SERIES_ID_1, 'r', 'p')
|
||||
self.nodes[CHILD].link_metrics_config_req_forward_tracking_series(leader_addr, SERIES_ID_1, 'r', 'p', 'async')
|
||||
self.simulator.go(1)
|
||||
|
||||
# 2. Child configures the same Forward Tracking Series again.
|
||||
# Child should get a response with status 2 (SERIES_ID_ALREADY_REGISTERED).
|
||||
self.nodes[CHILD].link_metrics_mgmt_req_forward_tracking_series(leader_addr, SERIES_ID_1, 'r', 'p')
|
||||
self.nodes[CHILD].link_metrics_config_req_forward_tracking_series(leader_addr, SERIES_ID_1, 'r', 'p', 'async')
|
||||
self.simulator.go(1)
|
||||
|
||||
# 3. Child queries a Series that doesn't exist (using a wrong Series ID).
|
||||
# Child should get a report with status 3 (SERIES_ID_NOT_RECOGNIZED).
|
||||
self.nodes[CHILD].link_metrics_query_forward_tracking_series(leader_addr, SERIES_ID_2)
|
||||
self.nodes[CHILD].link_metrics_request_forward_tracking_series(leader_addr, SERIES_ID_2, 'async')
|
||||
self.simulator.go(1)
|
||||
|
||||
# 4. Child queries a Series that don't have matched frames yet.
|
||||
# Child should get a report with status 4 (NO_MATCHING_FRAMES_RECEIVED).
|
||||
self.nodes[CHILD].link_metrics_query_forward_tracking_series(leader_addr, SERIES_ID_1)
|
||||
self.nodes[CHILD].link_metrics_request_forward_tracking_series(leader_addr, SERIES_ID_1, 'async')
|
||||
self.simulator.go(1)
|
||||
|
||||
# 5. Child clears a Forward Tracking Series that doesn't exist.
|
||||
# Child should get a response with status 3 (SERIES_ID_NOT_RECOGNIZED).
|
||||
self.nodes[CHILD].link_metrics_mgmt_req_forward_tracking_series(leader_addr, SERIES_ID_2, 'X', '')
|
||||
self.nodes[CHILD].link_metrics_config_req_forward_tracking_series(leader_addr, SERIES_ID_2, 'X', '', 'async')
|
||||
self.simulator.go(1)
|
||||
|
||||
# 6. Child clears a Forward Tracking Series successfully.
|
||||
# Child should get a response with status 0 (SUCCESS).
|
||||
self.nodes[CHILD].link_metrics_mgmt_req_forward_tracking_series(leader_addr, SERIES_ID_1, 'X', '')
|
||||
self.nodes[CHILD].link_metrics_config_req_forward_tracking_series(leader_addr, SERIES_ID_1, 'X', '', 'async')
|
||||
self.simulator.go(1)
|
||||
|
||||
# 7. Child configures a new Forward Tracking Series successfully.
|
||||
# The Series tracks the count of all MAC Data frames.
|
||||
# Child should get a response with status 0 (SUCCESS).
|
||||
self.nodes[CHILD].link_metrics_mgmt_req_forward_tracking_series(leader_addr, SERIES_ID_2, 'd', 'pqmr')
|
||||
self.nodes[CHILD].link_metrics_config_req_forward_tracking_series(leader_addr, SERIES_ID_2, 'd', 'pqmr',
|
||||
'async')
|
||||
self.simulator.go(1)
|
||||
|
||||
# 8. Child sends an MLE Link Probe message to the Subject for the newly configured Series.
|
||||
@@ -115,7 +116,7 @@ class LowPower_test_ForwardTrackingSeries(thread_cert.TestCase):
|
||||
|
||||
# 9. Child queries the newly configured Series successfully.
|
||||
# Child should get a report with valid values.
|
||||
self.nodes[CHILD].link_metrics_query_forward_tracking_series(leader_addr, SERIES_ID_2)
|
||||
self.nodes[CHILD].link_metrics_request_forward_tracking_series(leader_addr, SERIES_ID_2, 'async')
|
||||
self.simulator.go(1)
|
||||
|
||||
def verify(self, pv):
|
||||
|
||||
@@ -70,7 +70,7 @@ class SSED_SingleProbe(thread_cert.TestCase):
|
||||
leader_messages = self.simulator.get_messages_sent_by(LEADER)
|
||||
|
||||
# SSED_1 sends a Single Probe Link Metrics for L2 PDU count using MLE Data Request
|
||||
result = self.nodes[SSED_1].link_metrics_query_single_probe(leader_addr, 'p', 'block')
|
||||
result = self.nodes[SSED_1].link_metrics_request_single_probe(leader_addr, 'p')
|
||||
self.assertIn('PDU Counter', result)
|
||||
self.assertEqual(len(result), 1)
|
||||
|
||||
@@ -79,7 +79,7 @@ class SSED_SingleProbe(thread_cert.TestCase):
|
||||
msg.assertMleMessageContainsTlv(mle.LinkMetricsReport)
|
||||
|
||||
# SSED_1 sends a Single Probe Link Metrics for L2 LQI using MLE Data Request
|
||||
result = self.nodes[SSED_1].link_metrics_query_single_probe(leader_addr, 'q', 'block')
|
||||
result = self.nodes[SSED_1].link_metrics_request_single_probe(leader_addr, 'q')
|
||||
self.assertIn('LQI', result)
|
||||
self.assertEqual(len(result), 1)
|
||||
|
||||
@@ -88,7 +88,7 @@ class SSED_SingleProbe(thread_cert.TestCase):
|
||||
msg.assertMleMessageContainsTlv(mle.LinkMetricsReport)
|
||||
|
||||
# SSED_1 sends a Single Probe Link Metrics for Link Margin using MLE Data Request
|
||||
result = self.nodes[SSED_1].link_metrics_query_single_probe(leader_addr, 'm', 'block')
|
||||
result = self.nodes[SSED_1].link_metrics_request_single_probe(leader_addr, 'm')
|
||||
self.assertIn('Margin', result)
|
||||
self.assertEqual(len(result), 1)
|
||||
|
||||
@@ -97,7 +97,7 @@ class SSED_SingleProbe(thread_cert.TestCase):
|
||||
msg.assertMleMessageContainsTlv(mle.LinkMetricsReport)
|
||||
|
||||
# SSED_1 sends a Single Probe Link Metrics for Link Margin using MLE Data Request
|
||||
result = self.nodes[SSED_1].link_metrics_query_single_probe(leader_addr, 'r', 'block')
|
||||
result = self.nodes[SSED_1].link_metrics_request_single_probe(leader_addr, 'r')
|
||||
self.assertIn('RSSI', result)
|
||||
self.assertEqual(len(result), 1)
|
||||
|
||||
@@ -106,7 +106,7 @@ class SSED_SingleProbe(thread_cert.TestCase):
|
||||
msg.assertMleMessageContainsTlv(mle.LinkMetricsReport)
|
||||
|
||||
# SSED_1 sends a Single Probe Link Metrics for all metrics using MLE Data Request
|
||||
result = self.nodes[SSED_1].link_metrics_query_single_probe(leader_addr, 'pqmr', 'block')
|
||||
result = self.nodes[SSED_1].link_metrics_request_single_probe(leader_addr, 'pqmr')
|
||||
self.assertIn('PDU Counter', result)
|
||||
self.assertIn('LQI', result)
|
||||
self.assertIn('Margin', result)
|
||||
|
||||
Reference in New Issue
Block a user