1"""
2LwM2M Bootstrap interface tests
3###############################
4
5Copyright (c) 2023 Nordic Semiconductor ASA
6
7SPDX-License-Identifier: Apache-2.0
8
9Test specification:
10===================
11https://www.openmobilealliance.org/release/LightweightM2M/ETS/OMA-ETS-LightweightM2M-V1_1-20190912-D.pdf
12
13
14This module contains only testcases that verify the bootstrap.
15"""
16
17import logging
18import pytest
19from leshan import Leshan
20from twister_harness import Shell
21from twister_harness import DeviceAdapter
22from conftest import Endpoint
23
24logger = logging.getLogger(__name__)
25
26
27#
28# Test specification:
29# https://www.openmobilealliance.org/release/LightweightM2M/ETS/OMA-ETS-LightweightM2M-V1_1-20190912-D.pdf
30#
31# Bootstrap Interface: [0-99]
32#
33
34def verify_LightweightM2M_1_1_int_0(dut: DeviceAdapter, endpoint_bootstrap: Endpoint):
35    """LightweightM2M-1.1-int-0 - Client Initiated Bootstrap"""
36    dut.readlines_until(regex='.*Bootstrap transfer complete', timeout=5.0)
37    endpoint_bootstrap.bootstrap = True
38
39def test_LightweightM2M_1_1_int_1(shell: Shell, dut: DeviceAdapter, leshan: Leshan, endpoint_bootstrap: Endpoint):
40    """LightweightM2M-1.1-int-1 - Client Initiated Bootstrap Full (PSK)"""
41    verify_LightweightM2M_1_1_int_0(dut, endpoint_bootstrap)
42    verify_LightweightM2M_1_1_int_101(shell, dut, leshan, endpoint_bootstrap)
43    verify_LightweightM2M_1_1_int_401(shell, leshan, endpoint_bootstrap)
44
45def test_LightweightM2M_1_1_int_4(shell: Shell, dut: DeviceAdapter, leshan: Leshan, endpoint: Endpoint):
46    """LightweightM2M-1.1-int-4 - Bootstrap Delete"""
47    shell.exec_command('lwm2m create 1/2')
48    shell.exec_command('lwm2m read 1/2/0')
49    retval = int(shell.get_filtered_output(shell.exec_command('retval'))[0])
50    assert retval == 0
51    leshan.execute(endpoint, '1/0/9')
52    dut.readlines_until(regex='.*Registration Done', timeout=5.0)
53    shell.exec_command('lwm2m read 1/2/0')
54    retval = int(shell.get_filtered_output(shell.exec_command('retval'))[0])
55    assert retval < 0
56    logger.info('retval: %s', retval)
57
58def test_LightweightM2M_1_1_int_5(dut: DeviceAdapter, leshan: Leshan, endpoint: Endpoint):
59    """LightweightM2M-1.1-int-5 - Server Initiated Bootstrap"""
60    leshan.execute(endpoint, '1/0/9')
61    dut.readlines_until(regex='.*Server Initiated Bootstrap', timeout=1)
62    dut.readlines_until(regex='.*Bootstrap transfer complete', timeout=5.0)
63    dut.readlines_until(regex='.*Registration Done', timeout=5.0)
64
65def test_LightweightM2M_1_1_int_6(shell: Shell, dut: DeviceAdapter, endpoint: Endpoint):
66    """LightweightM2M-1.1-int-6 - Bootstrap Sequence"""
67    shell.exec_command('lwm2m stop')
68    dut.readlines_until(regex=r'.*Deregistration success', timeout=5)
69    shell.exec_command(f'lwm2m start {endpoint}')
70    lines = dut.readlines_until(regex='.*Registration Done', timeout=5.0)
71    assert not any("Bootstrap" in line for line in lines)
72    shell.exec_command('lwm2m stop')
73    dut.readlines_until(regex=r'.*Deregistration success', timeout=5)
74    shell.exec_command("lwm2m delete 1/0")
75    shell.exec_command("lwm2m delete 0/1")
76    shell.exec_command(f'lwm2m start {endpoint}')
77    lines = dut.readlines_until(regex='.*Registration Done', timeout=5.0)
78    assert any("Bootstrap" in line for line in lines)
79
80@pytest.mark.slow
81def test_LightweightM2M_1_1_int_7(shell: Shell, dut: DeviceAdapter, endpoint: Endpoint):
82    """LightweightM2M-1.1-int-7 - Fallback to bootstrap"""
83    shell.exec_command('lwm2m stop')
84    dut.readlines_until(regex=r'.*Deregistration success', timeout=5)
85    shell.exec_command('lwm2m write 0/1/0 -s coaps://10.10.10.10:5684')
86    shell.exec_command(f'lwm2m start {endpoint}')
87    lines = dut.readlines_until(regex='.*Registration Done', timeout=600.0)
88    assert any("Bootstrap" in line for line in lines)
89
90def verify_LightweightM2M_1_1_int_101(shell: Shell, dut: DeviceAdapter, leshan: Leshan, endpoint: Endpoint):
91    """LightweightM2M-1.1-int-101 - Initial Registration"""
92    dut.readlines_until(regex='.*Registration Done', timeout=5.0)
93    assert leshan.get(f'/clients/{endpoint}')
94    endpoint.registered = True
95
96def verify_LightweightM2M_1_1_int_401(shell: Shell, leshan: Leshan, endpoint: Endpoint):
97    """LightweightM2M-1.1-int-401 - UDP Channel Security - Pre-shared Key Mode"""
98    lines = shell.get_filtered_output(shell.exec_command('lwm2m read 0/0/0 -s'))
99    host = lines[0]
100    assert 'coaps://' in host
101    lines = shell.get_filtered_output(shell.exec_command('lwm2m read 0/0/2 -u8'))
102    mode = int(lines[0])
103    assert mode == 0
104    resp = leshan.get(f'/clients/{endpoint}')
105    assert resp["secure"]
106