Skip to content

Commit

Permalink
[test] test whether the RCP supports tx/rx 154 frames of all formats (o…
Browse files Browse the repository at this point in the history
…penthread#10912)

This commit add a command `--frame-format` to the `cp-caps` to test
whether the RCP supports sending and receiving 802.15.4 frames of all
formats.
  • Loading branch information
zhanglongxia authored Nov 13, 2024
1 parent 659b427 commit cc8f078
Show file tree
Hide file tree
Showing 2 changed files with 218 additions and 33 deletions.
72 changes: 62 additions & 10 deletions tools/cp-caps/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,26 +54,28 @@ Show help info.

```bash
$ python3 ./tools/cp-caps/rcp_caps_test.py -h
usage: rcp_caps_test.py [-h] [-c] [-d] [-p] [-t] [-v] [-D]
usage: rcp_caps_test.py [-h] [-c] [-l] [-d] [-f] [-p] [-t] [-v] [-D]

This script is used for testing RCP capabilities.

options:
-h, --help show this help message and exit
-c, --csl test whether the RCP supports CSL transmitter
-d, --diag-commands test whether the RCP supports all diag commands
-l, --link-metrics test whether the RCP supports link metrics
-d, --diag-commands test whether the RCP supports all diag commands
-f, --frame-format test whether the RCP supports 802.15.4 frames of all formats
-p, --data-poll test whether the RCP supports data poll
-t, --throughput test the Thread network 1-hop throughput
-t, --throughput test Thread network 1-hop throughput
-v, --version output version
-D, --debug output debug information

Device Interfaces:
DUT_SSH=<device_ip> Connect to the DUT via ssh
DUT_ADB_TCP=<device_ip> Connect to the DUT via adb tcp
DUT_ADB_USB=<serial_number> Connect to the DUT via adb usb
REF_CLI_SERIAL=<serial_device> Connect to the reference device via cli serial port
DUT_CLI_SERIAL=<serial_device> Connect to the DUT via cli serial port
DUT_SSH=<device_ip> Connect to the DUT via ssh
REF_ADB_USB=<serial_number> Connect to the reference device via adb usb
REF_CLI_SERIAL=<serial_device> Connect to the reference device via cli serial port
REF_SSH=<device_ip> Connect to the reference device via ssh

Example:
Expand All @@ -82,7 +84,7 @@ Example:

### Test Diag Commands

The parameter `-d` or `--diag-commands` starts to test all diag commands.
The option `-d` or `--diag-commands` tests all diag commands.

Following environment variables are used to configure diag command parameters:

Expand Down Expand Up @@ -131,7 +133,7 @@ diag gpio set 2 1 ---------------------------------------- NotSupported

### Test CSL Transmitter

The parameter `-c` or `--csl` starts to test whether the RCP supports the CSL transmitter.
The option `-c` or `--csl` tests whether the RCP supports the CSL transmitter.

```bash
$ DUT_ADB_USB=TW69UCKFZTGM95OR REF_CLI_SERIAL=/dev/ttyACM0 python3 ./tools/cp-caps/rcp_caps_test.py -c
Expand All @@ -140,7 +142,7 @@ CSL Transmitter ------------------------------------------ OK

### Test Data Poll

The parameter `-p` or `--data-poll` starts to test whether the RCP supports data poll.
The option `-p` or `--data-poll` tests whether the RCP supports data poll.

```bash
$ DUT_ADB_USB=1269UCKFZTAM95OR REF_CLI_SERIAL=/dev/ttyACM0 python3 ./tools/cp-caps/rcp_caps_test.py -p
Expand All @@ -150,7 +152,7 @@ Data Poll Child ------------------------------------------ OK

### Test Link Metrics

The parameter `-l` or `--link-metrics` starts to test whether the RCP supports link metrics.
The option `-l` or `--link-metrics` tests whether the RCP supports link metrics.

```bash
$ DUT_ADB_USB=1269UCKFZTAM95OR REF_CLI_SERIAL=/dev/ttyACM0 python3 ./tools/cp-caps/rcp_caps_test.py -l
Expand All @@ -160,9 +162,59 @@ Link Metrics Subject ------------------------------------- OK

### Test Throughput

The parameter `-t` or `--throughput` starts to test the Thread network 1-hop throughput of the DUT.
The option `-t` or `--throughput` tests the Thread network 1-hop throughput of the DUT.

```bash
$ DUT_ADB_USB=1269UCKFZTAM95OR REF_ADB_USB=44061HFAG01AQK python3 ./tools/cp-caps/rcp_caps_test.py -t
Throughput ----------------------------------------------- 75.6 Kbits/sec
```

### Test Frame Format

The option `-f` or `--frame-format` tests whether the RCP supports sending and receiving 802.15.4 frames of all formats.

```bash
$ DUT_ADB_USB=1269UCKFZTAM95OR REF_CLI_SERIAL=/dev/ttyACM0 python3 ./tools/cp-caps/rcp_caps_test.py -f
TX ver:2003,Cmd,seq,dst[addr:short,pan:id],src[addr:no,pan:no],sec:no,ie:no,plen:0 ----------------- OK
RX ver:2003,Cmd,seq,dst[addr:short,pan:id],src[addr:no,pan:no],sec:no,ie:no,plen:0 ----------------- OK
TX ver:2003,Bcon,seq,dst[addr:no,pan:no],src[addr:extd,pan:id],sec:no,ie:no,plen:30 ---------------- OK
RX ver:2003,Bcon,seq,dst[addr:no,pan:no],src[addr:extd,pan:id],sec:no,ie:no,plen:30 ---------------- OK
TX ver:2006,Cmd,seq,dst[addr:short,pan:id],src[addr:short,pan:no],sec:l5,ie:no,plen:0 -------------- OK
RX ver:2006,Cmd,seq,dst[addr:short,pan:id],src[addr:short,pan:no],sec:l5,ie:no,plen:0 -------------- OK
TX ver:2006,Cmd,seq,dst[addr:extd,pan:id],src[addr:extd,pan:no],sec:l5,ie:no,plen:0 ---------------- OK
RX ver:2006,Cmd,seq,dst[addr:extd,pan:id],src[addr:extd,pan:no],sec:l5,ie:no,plen:0 ---------------- OK
TX ver:2006,Data,seq,dst[addr:extd,pan:id],src[addr:extd,pan:id],sec:no,ie:no,plen:0 --------------- OK
RX ver:2006,Data,seq,dst[addr:extd,pan:id],src[addr:extd,pan:id],sec:no,ie:no,plen:0 --------------- OK
TX ver:2006,Data,seq,dst[addr:short,pan:id],src[addr:short,pan:id],sec:no,ie:no,plen:0 ------------- OK
RX ver:2006,Data,seq,dst[addr:short,pan:id],src[addr:short,pan:id],sec:no,ie:no,plen:0 ------------- OK
TX ver:2006,Data,seq,dst[addr:extd,pan:id],src[addr:no,pan:no],sec:no,ie:no,plen:0 ----------------- OK
RX ver:2006,Data,seq,dst[addr:extd,pan:id],src[addr:no,pan:no],sec:no,ie:no,plen:0 ----------------- OK
TX ver:2006,Data,seq,dst[addr:short,pan:id],src[addr:no,pan:no],sec:no,ie:no,plen:0 ---------------- OK
RX ver:2006,Data,seq,dst[addr:short,pan:id],src[addr:no,pan:no],sec:no,ie:no,plen:0 ---------------- OK
TX ver:2015,Data,seq,dst[addr:no,pan:no],src[addr:no,pan:no],sec:no,ie:no,plen:0 ------------------- OK
RX ver:2015,Data,seq,dst[addr:no,pan:no],src[addr:no,pan:no],sec:no,ie:no,plen:0 ------------------- OK
TX ver:2015,Data,seq,dst[addr:no,pan:id],src[addr:no,pan:no],sec:no,ie:no,plen:0 ------------------- OK
RX ver:2015,Data,seq,dst[addr:no,pan:id],src[addr:no,pan:no],sec:no,ie:no,plen:0 ------------------- OK
TX ver:2015,Data,seq,dst[addr:extd,pan:id],src[addr:no,pan:no],sec:no,ie:no,plen:0 ----------------- OK
RX ver:2015,Data,seq,dst[addr:extd,pan:id],src[addr:no,pan:no],sec:no,ie:no,plen:0 ----------------- OK
TX ver:2015,Data,seq,dst[addr:extd,pan:no],src[addr:no,pan:no],sec:no,ie:no,plen:0 ----------------- OK
RX ver:2015,Data,seq,dst[addr:extd,pan:no],src[addr:no,pan:no],sec:no,ie:no,plen:0 ----------------- OK
TX ver:2015,Data,seq,dst[addr:no,pan:no],src[addr:extd,pan:id],sec:no,ie:no,plen:0 ----------------- OK
RX ver:2015,Data,seq,dst[addr:no,pan:no],src[addr:extd,pan:id],sec:no,ie:no,plen:0 ----------------- OK
TX ver:2015,Data,seq,dst[addr:no,pan:no],src[addr:extd,pan:no],sec:no,ie:no,plen:0 ----------------- OK
RX ver:2015,Data,seq,dst[addr:no,pan:no],src[addr:extd,pan:no],sec:no,ie:no,plen:0 ----------------- OK
TX ver:2015,Data,seq,dst[addr:extd,pan:id],src[addr:extd,pan:no],sec:no,ie:no,plen:0 --------------- OK
RX ver:2015,Data,seq,dst[addr:extd,pan:id],src[addr:extd,pan:no],sec:no,ie:no,plen:0 --------------- OK
TX ver:2015,Data,seq,dst[addr:extd,pan:no],src[addr:extd,pan:no],sec:no,ie:no,plen:0 --------------- OK
RX ver:2015,Data,seq,dst[addr:extd,pan:no],src[addr:extd,pan:no],sec:no,ie:no,plen:0 --------------- OK
TX ver:2015,Data,seq,dst[addr:short,pan:id],src[addr:short,pan:id],sec:no,ie:no,plen:0 ------------- OK
RX ver:2015,Data,seq,dst[addr:short,pan:id],src[addr:short,pan:id],sec:no,ie:no,plen:0 ------------- OK
TX ver:2015,Data,seq,dst[addr:short,pan:id],src[addr:extd,pan:id],sec:no,ie:no,plen:0 -------------- OK
RX ver:2015,Data,seq,dst[addr:short,pan:id],src[addr:extd,pan:id],sec:no,ie:no,plen:0 -------------- OK
TX ver:2015,Data,seq,dst[addr:extd,pan:id],src[addr:short,pan:id],sec:no,ie:no,plen:0 -------------- OK
RX ver:2015,Data,seq,dst[addr:extd,pan:id],src[addr:short,pan:id],sec:no,ie:no,plen:0 -------------- OK
TX ver:2015,Data,seq,dst[addr:short,pan:id],src[addr:short,pan:id],sec:no,ie[csl],plen:0 ----------- OK
RX ver:2015,Data,seq,dst[addr:short,pan:id],src[addr:short,pan:id],sec:no,ie[csl],plen:0 ----------- OK
TX ver:2015,Data,noseq,dst[addr:short,pan:id],src[addr:short,pan:id],sec:no,ie:no,plen:0 ----------- OK
RX ver:2015,Data,noseq,dst[addr:short,pan:id],src[addr:short,pan:id],sec:no,ie:no,plen:0 ----------- OK
```
179 changes: 156 additions & 23 deletions tools/cp-caps/rcp_caps_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
from otci import OTCI
from otci.types import Ip6Addr

CP_CAPABILITY_VERSION = "0.1.0"
CP_CAPABILITY_VERSION = "0.1.1-dev"

logging.basicConfig(level=logging.WARNING)

Expand All @@ -50,6 +50,8 @@ class RcpCaps(object):
This class represents an OpenThread RCP capability test instance.
"""

DEFAULT_FORMAT_ALIGN_LENGTH = 58 # The default formatted string alignment length

def __init__(self):
self.__dut = self.__connect_dut()
self.__ref = self.__connect_reference_device()
Expand Down Expand Up @@ -83,6 +85,113 @@ def test_diag_commands(self):
self.__ref.diag_stop()
self.__dut.diag_stop()

def test_frame_format(self):
"""Test whether the DUT supports sending and receiving 802.15.4 frames of all formats."""
frames = [
{
'name': 'ver:2003,Cmd,seq,dst[addr:short,pan:id],src[addr:no,pan:no],sec:no,ie:no,plen:0',
'psdu': '030800ffffffff070000'
},
{
'name': 'ver:2003,Bcon,seq,dst[addr:no,pan:no],src[addr:extd,pan:id],sec:no,ie:no,plen:30',
'psdu': '00c000eeee0102030405060708ff0f000003514f70656e54687265616400000000000001020304050607080000'
},
{
'name': 'ver:2006,Cmd,seq,dst[addr:short,pan:id],src[addr:short,pan:no],sec:l5,ie:no,plen:0',
'psdu': '4b98ddddddaaaabbbb0d708001020304050607081565'
},
{
'name': 'ver:2006,Cmd,seq,dst[addr:extd,pan:id],src[addr:extd,pan:no],sec:l5,ie:no,plen:0',
'psdu': '4bdcdddddd102030405060708001020304050607080d6e54687265046400820ee803'
},
{
'name': 'ver:2006,Data,seq,dst[addr:extd,pan:id],src[addr:extd,pan:id],sec:no,ie:no,plen:0',
'psdu': '01dcdddddd1020304050607080000001020304050607085468'
},
{
'name': 'ver:2006,Data,seq,dst[addr:short,pan:id],src[addr:short,pan:id],sec:no,ie:no,plen:0',
'psdu': '0198ddddddaaaaeeeebbbb7080'
},
{
'name': 'ver:2006,Data,seq,dst[addr:extd,pan:id],src[addr:no,pan:no],sec:no,ie:no,plen:0',
'psdu': '011cdddddd10203040506070800000'
},
{
'name': 'ver:2006,Data,seq,dst[addr:short,pan:id],src[addr:no,pan:no],sec:no,ie:no,plen:0',
'psdu': '0118ddddddaaaa3040'
},
{
'name': 'ver:2015,Data,seq,dst[addr:no,pan:no],src[addr:no,pan:no],sec:no,ie:no,plen:0',
'psdu': '0120dddddd'
},
{
'name': 'ver:2015,Data,seq,dst[addr:no,pan:id],src[addr:no,pan:no],sec:no,ie:no,plen:0',
'psdu': '4120ddddddaaaa'
},
{
'name': 'ver:2015,Data,seq,dst[addr:extd,pan:id],src[addr:no,pan:no],sec:no,ie:no,plen:0',
'psdu': '012cdddddd10203040506070800000'
},
{
'name': 'ver:2015,Data,seq,dst[addr:extd,pan:no],src[addr:no,pan:no],sec:no,ie:no,plen:0',
'psdu': '412cdd10203040506070807080'
},
{
'name': 'ver:2015,Data,seq,dst[addr:no,pan:no],src[addr:extd,pan:id],sec:no,ie:no,plen:0',
'psdu': '01e0ddeeee01020304050607080000'
},
{
'name': 'ver:2015,Data,seq,dst[addr:no,pan:no],src[addr:extd,pan:no],sec:no,ie:no,plen:0',
'psdu': '41e0dd01020304050607080708'
},
{
'name': 'ver:2015,Data,seq,dst[addr:extd,pan:id],src[addr:extd,pan:no],sec:no,ie:no,plen:0',
'psdu': '01ecdddddd102030405060708001020304050607080708'
},
{
'name': 'ver:2015,Data,seq,dst[addr:extd,pan:no],src[addr:extd,pan:no],sec:no,ie:no,plen:0',
'psdu': '41ecdd102030405060708001020304050607080708'
},
{
'name': 'ver:2015,Data,seq,dst[addr:short,pan:id],src[addr:short,pan:id],sec:no,ie:no,plen:0',
'psdu': '01a8ddddddaaaaeeeebbbb0102'
},
{
'name': 'ver:2015,Data,seq,dst[addr:short,pan:id],src[addr:extd,pan:id],sec:no,ie:no,plen:0',
'psdu': '01e8ddddddaaaaeeee01020304050607080708'
},
{
'name': 'ver:2015,Data,seq,dst[addr:extd,pan:id],src[addr:short,pan:id],sec:no,ie:no,plen:0',
'psdu': '01acdddddd1020304050607080eeeebbbb0708'
},
{
'name': 'ver:2015,Data,seq,dst[addr:short,pan:id],src[addr:short,pan:id],sec:no,ie[csl],plen:0',
'psdu': '01aaddddddaaaaeeeebbbb040dc800e8030708'
},
{
'name': 'ver:2015,Data,noseq,dst[addr:short,pan:id],src[addr:short,pan:id],sec:no,ie:no,plen:0',
'psdu': '01a9ddddaaaaeeeebbbbbb04'
},
]

self.__dut.factory_reset()
self.__ref.factory_reset()

ret = self.__dut.is_command_supported('diag start')
if ret is False:
print('Diag commands are not supported')
return

self.__dut.diag_start()
self.__ref.diag_start()

for frame in frames:
self.__test_send_formated_frame(self.__dut, self.__ref, 'TX ' + frame['name'], frame['psdu'], 100)
self.__test_send_formated_frame(self.__ref, self.__dut, 'RX ' + frame['name'], frame['psdu'], 100)

self.__ref.diag_stop()
self.__dut.diag_stop()

def test_csl(self):
"""Test whether the DUT supports CSL transmitter."""
self.__dataset = self.__get_default_dataset()
Expand Down Expand Up @@ -476,34 +585,44 @@ def __test_diag_repeat(self):
self.__output_format_bool(cmd_diag_repeat, ret)
self.__output_format_bool(cmd_diag_repeat_stop, ret)

def __test_diag_frame(self):
def __test_send_formated_frame(self,
sender: OTCI,
receiver: OTCI,
format_name: str,
frame: str,
align_length: int = DEFAULT_FORMAT_ALIGN_LENGTH):
packets = 100
threshold = 80
channel = 20
frame = '00010203040506070809'
cmd_diag_frame = f'diag frame {frame}'
commands = [cmd_diag_frame, f'diag send {packets}', f'diag stats', f'diag stats clear']

if self.__support_commands(commands):
self.__dut.wait(1)
self.__dut.diag_set_channel(channel)
self.__ref.diag_set_channel(channel)
self.__ref.diag_radio_receive()
sender.wait(1)
sender.diag_set_channel(channel)
receiver.diag_set_channel(channel)
receiver.diag_radio_receive()

self.__dut.diag_stats_clear()
self.__ref.diag_stats_clear()
sender.diag_stats_clear()
sender.diag_stats_clear()

self.__ref.diag_frame(frame)
self.__dut.diag_send(packets, None)
self.__dut.wait(1)
dut_stats = self.__dut.diag_get_stats()
ref_stats = self.__ref.diag_get_stats()
sender.diag_frame(frame)
sender.diag_send(packets, None)
sender.wait(1)
sender_stats = sender.diag_get_stats()
receiver_stats = receiver.diag_get_stats()

ret = dut_stats['sent_packets'] == packets and ref_stats['received_packets'] > threshold
ret = sender_stats['sent_packets'] == packets and receiver_stats['received_packets'] > threshold
else:
ret = False

self.__output_format_bool(cmd_diag_frame, ret)
self.__output_format_bool(format_name, ret, align_length)

def __test_diag_frame(self):
frame = '00010203040506070809'
cmd_diag_frame = f'diag frame {frame}'

self.__test_send_formated_frame(self.__dut, self.__ref, cmd_diag_frame, frame)

def __support_commands(self, commands: List[str]) -> bool:
ret = True
Expand Down Expand Up @@ -533,10 +652,12 @@ def __connect_dut(self) -> OTCI:
node = otci.connect_otbr_adb_tcp(os.getenv('DUT_ADB_TCP'))
elif os.getenv('DUT_ADB_USB'):
node = otci.connect_otbr_adb_usb(os.getenv('DUT_ADB_USB'))
elif os.getenv('DUT_CLI_SERIAL'):
node = otci.connect_cli_serial(os.getenv('DUT_CLI_SERIAL'))
elif os.getenv('DUT_SSH'):
node = otci.connect_otbr_ssh(os.getenv('DUT_SSH'))
else:
self.__fail("Please set DUT_ADB_TCP, DUT_ADB_USB or DUT_SSH to connect to the DUT device.")
self.__fail("Please set DUT_ADB_TCP, DUT_ADB_USB, DUT_CLI_SERIAL or DUT_SSH to connect to the DUT device.")

return node

Expand All @@ -552,12 +673,12 @@ def __connect_reference_device(self) -> OTCI:

return node

def __output_format_string(self, name: str, value: str):
prefix = '{0:-<58}'.format('{} '.format(name))
def __output_format_string(self, name: str, value: str, align_length: int = DEFAULT_FORMAT_ALIGN_LENGTH):
prefix = (name + ' ').ljust(align_length, '-')
print(f'{prefix} {value}')

def __output_format_bool(self, name: str, value: bool):
self.__output_format_string(name, 'OK' if value else 'NotSupported')
def __output_format_bool(self, name: str, value: bool, align_length: int = DEFAULT_FORMAT_ALIGN_LENGTH):
self.__output_format_string(name, 'OK' if value else 'NotSupported', align_length)

def __fail(self, value: str):
print(f'{value}')
Expand All @@ -569,11 +690,12 @@ def parse_arguments():
description_msg = 'This script is used for testing RCP capabilities.'
epilog_msg = textwrap.dedent(
'Device Interfaces:\r\n'
' DUT_SSH=<device_ip> Connect to the DUT via ssh\r\n'
' DUT_ADB_TCP=<device_ip> Connect to the DUT via adb tcp\r\n'
' DUT_ADB_USB=<serial_number> Connect to the DUT via adb usb\r\n'
' REF_CLI_SERIAL=<serial_device> Connect to the reference device via cli serial port\r\n'
' DUT_CLI_SERIAL=<serial_device> Connect to the DUT via cli serial port\r\n'
' DUT_SSH=<device_ip> Connect to the DUT via ssh\r\n'
' REF_ADB_USB=<serial_number> Connect to the reference device via adb usb\r\n'
' REF_CLI_SERIAL=<serial_device> Connect to the reference device via cli serial port\r\n'
' REF_SSH=<device_ip> Connect to the reference device via ssh\r\n'
'\r\n'
'Example:\r\n'
Expand Down Expand Up @@ -607,6 +729,14 @@ def parse_arguments():
help='test whether the RCP supports all diag commands',
)

parser.add_argument(
'-f',
'--frame-format',
action='store_true',
default=False,
help='test whether the RCP supports 802.15.4 frames of all formats',
)

parser.add_argument(
'-p',
'--data-poll',
Expand Down Expand Up @@ -670,6 +800,9 @@ def main():
if arguments.throughput:
rcp_caps.test_throughput()

if arguments.frame_format:
rcp_caps.test_frame_format()


if __name__ == '__main__':
main()

0 comments on commit cc8f078

Please sign in to comment.