Skip to content

Commit

Permalink
[test] test whether the RCP supports tx/rx 154 frames of all formats
Browse files Browse the repository at this point in the history
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 committed Nov 11, 2024
1 parent 0fb1c22 commit 08c8a25
Show file tree
Hide file tree
Showing 2 changed files with 164 additions and 27 deletions.
62 changes: 57 additions & 5 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] [-p] [-t] [-v] [-D] [--frame-format]

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
-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
--frame-format test whether the RCP supports 802.15.4 frames of all formats

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 Down Expand Up @@ -166,3 +168,53 @@ The parameter `-t` or `--throughput` starts to test the Thread network 1-hop thr
$ 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 parameter `--frame-format` starts to test 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 --frame-format
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
```
129 changes: 107 additions & 22 deletions tools/cp-caps/rcp_caps_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,71 @@ def test_diag_commands(self):
self.__ref.diag_stop()
self.__dut.diag_stop()

def test_frame_format(self):
"""Test all diag commands."""
self.__dut.factory_reset()
self.__ref.factory_reset()

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

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.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 +543,39 @@ 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 +605,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 +626,13 @@ 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):
name = name + ' '
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 +644,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 @@ -639,6 +715,13 @@ def parse_arguments():
help='output debug information',
)

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

return parser.parse_args()


Expand Down Expand Up @@ -670,6 +753,8 @@ 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 08c8a25

Please sign in to comment.