tests: Bluetooth: Mesh: Test Node Composition refresh with settings

Test Node Composition Refresh procedure with persistence settings.

Signed-off-by: Pavel Vasilyev <pavel.vasilyev@nordicsemi.no>
This commit is contained in:
Pavel Vasilyev 2022-10-28 17:19:21 +02:00 committed by Carles Cufí
commit 316d7fcd57
6 changed files with 332 additions and 22 deletions

View file

@ -29,6 +29,7 @@ if(CONFIG_SETTINGS)
src/settings_test_backend.c
src/test_persistence.c
src/test_replay_cache.c
src/test_provision.c
)
if(CONFIG_BT_MESH_V1d1)

View file

@ -10,6 +10,7 @@
#if defined(CONFIG_SETTINGS)
extern struct bst_test_list *test_persistence_install(struct bst_test_list *tests);
extern struct bst_test_list *test_rpc_install(struct bst_test_list *tests);
extern struct bst_test_list *test_provision_pst_install(struct bst_test_list *tests);
#if defined(CONFIG_BT_MESH_V1d1)
extern struct bst_test_list *test_dfu_install(struct bst_test_list *test);
#endif /* defined(CONFIG_BT_MESH_V1d1) */
@ -38,6 +39,7 @@ bst_test_install_t test_installers[] = {
test_persistence_install,
test_rpc_install,
#if defined(CONFIG_BT_MESH_V1d1)
test_provision_pst_install,
test_dfu_install,
#endif /* defined(CONFIG_BT_MESH_V1d1) */
#elif defined(CONFIG_BT_MESH_GATT_PROXY)

View file

@ -9,6 +9,7 @@
#include "mesh/access.h"
#include "mesh/net.h"
#include "argparse.h"
#include "settings_test_backend.h"
#include <bs_pc_backchannel.h>
#include <time_machine.h>
@ -115,6 +116,21 @@ static const struct bt_mesh_comp rpr_srv_comp = {
},
.elem_count = 1,
};
static const struct bt_mesh_comp rpr_srv_comp_2_elem = {
.elem =
(struct bt_mesh_elem[]){
BT_MESH_ELEM(1,
MODEL_LIST(BT_MESH_MODEL_CFG_SRV,
BT_MESH_MODEL_RPR_SRV),
BT_MESH_MODEL_NONE),
BT_MESH_ELEM(2,
MODEL_LIST(BT_MESH_MODEL_CB(TEST_MOD_ID, BT_MESH_MODEL_NO_OPS,
NULL, NULL, NULL)),
BT_MESH_MODEL_NONE),
},
.elem_count = 2,
};
#endif /* IS_RPR_PRESENT */
/* Delayed work to avoid requesting OOB info before generation of this. */
@ -716,6 +732,36 @@ static void provisioner_pb_remote_client_setup(void)
ASSERT_OK(bt_mesh_provision(test_net_key, 0, 0, 0, 0x0001, dev_key));
}
static void device_pb_remote_server_setup(const struct bt_mesh_comp *comp, bool pb_adv_prov)
{
k_sem_init(&prov_sem, 0, 1);
k_sem_init(&reprov_sem, 0, 1);
bt_mesh_device_setup(&prov, comp);
if (pb_adv_prov) {
ASSERT_OK(bt_mesh_prov_enable(BT_MESH_PROV_ADV));
LOG_INF("Waiting for being provisioned...");
ASSERT_OK(k_sem_take(&prov_sem, K_SECONDS(20)));
} else {
ASSERT_TRUE(bt_mesh_is_provisioned());
}
LOG_INF("Enabling PB-Remote server");
ASSERT_OK(bt_mesh_prov_enable(BT_MESH_PROV_REMOTE));
}
static void device_pb_remote_server_setup_unproved(const struct bt_mesh_comp *comp)
{
device_pb_remote_server_setup(comp, true);
}
static void device_pb_remote_server_setup_proved(const struct bt_mesh_comp *comp)
{
device_pb_remote_server_setup(comp, false);
}
/** @brief Verify that the provisioner can provision a device multiple times after resets using
* PB-Remote and RPR models.
*/
@ -725,7 +771,7 @@ static void test_provisioner_pb_remote_client_reprovision(void)
provisioner_pb_remote_client_setup();
/* Only provision the second device over PB-ADV. This device has RPR Server. */
/* Provision the 2nd device over PB-Adv. */
ASSERT_OK(provision_adv(1, &pb_remote_server_addr));
for (int i = 0; i < PROV_REPROV_COUNT; i++) {
@ -759,7 +805,7 @@ static void test_provisioner_pb_remote_client_nppi_robustness(void)
provisioner_pb_remote_client_setup();
/* Only provision the second device over PB-ADV. This device has RPR Server. */
/* Provision the 2nd device over PB-Adv. */
ASSERT_OK(provision_adv(1, &pb_remote_server_addr));
/* Provision a remote device with RPR Server. */
@ -869,23 +915,26 @@ static void test_provisioner_pb_remote_client_nppi_robustness(void)
PASS();
}
/** @brief A device running a Remote Provisioning server that can be used to provision
* unprovisioned devices.
/** @brief A device running a Remote Provisioning server that is used to provision unprovisioned
* devices over PB-Remote. Always starts unprovisioned.
*/
static void test_device_pb_remote_server(void)
static void test_device_pb_remote_server_unproved(void)
{
k_sem_init(&prov_sem, 0, 1);
#if defined(CONFIG_BT_SETTINGS)
settings_test_backend_clear();
#endif
bt_mesh_device_setup(&prov, &rpr_srv_comp);
device_pb_remote_server_setup_unproved(&rpr_srv_comp);
ASSERT_OK(bt_mesh_prov_enable(BT_MESH_PROV_ADV));
PASS();
}
LOG_INF("Mesh initialized\n");
ASSERT_OK(k_sem_take(&prov_sem, K_SECONDS(10)));
LOG_INF("Enabling PB-Remote server");
ASSERT_OK(bt_mesh_prov_enable(BT_MESH_PROV_REMOTE));
/** @brief A device running a Remote Provisioning server that is used to provision unprovisioned
* devices over PB-Remote. Starts provisioned.
*/
static void test_device_pb_remote_server_proved(void)
{
device_pb_remote_server_setup_proved(&rpr_srv_comp);
PASS();
}
@ -972,6 +1021,181 @@ static void test_device_pb_remote_server_nppi_robustness(void)
PASS();
}
/** @brief Test Node Composition Refresh procedure on Remote Provisioning client:
* - provision a device over PB-Adv,
* - provision a remote device over PB-Remote.
*/
static void test_provisioner_pb_remote_client_ncrp_provision(void)
{
uint16_t pb_remote_server_addr;
uint8_t status;
settings_test_backend_clear();
provisioner_pb_remote_client_setup();
/* Provision the 2nd device over PB-Adv. */
ASSERT_OK(provision_adv(1, &pb_remote_server_addr));
/* Provision the 3rd device over PB-Remote. */
struct bt_mesh_rpr_node srv = {
.addr = pb_remote_server_addr,
.net_idx = 0,
.ttl = 3,
};
ASSERT_OK(provision_remote(&srv, 2, &srv.addr));
/* Check device key by adding appkey. */
ASSERT_OK(bt_mesh_cfg_cli_app_key_add(0, pb_remote_server_addr, 0, 0, test_app_key,
&status));
ASSERT_OK(status);
PASS();
}
/** @brief Test Node Composition Refresh procedure on Remote Provisioning client:
* - initiate Node Composition Refresh procedure on a 3rd device.
*/
static void test_provisioner_pb_remote_client_ncrp(void)
{
NET_BUF_SIMPLE_DEFINE(dev_comp_p0, BT_MESH_RX_SDU_MAX);
NET_BUF_SIMPLE_DEFINE(dev_comp_p128, BT_MESH_RX_SDU_MAX);
uint16_t pb_remote_server_addr = 0x0003;
uint8_t page;
k_sem_init(&prov_sem, 0, 1);
k_sem_init(&reprov_sem, 0, 1);
bt_mesh_device_setup(&prov, &rpr_cli_comp);
/* Store Composition Data Page 0 and 128. */
ASSERT_OK(bt_mesh_cfg_cli_comp_data_get(0, pb_remote_server_addr, 0, &page, &dev_comp_p0));
ASSERT_EQUAL(0, page);
ASSERT_OK(bt_mesh_cfg_cli_comp_data_get(0, pb_remote_server_addr, 128, &page,
&dev_comp_p128));
ASSERT_EQUAL(128, page);
ASSERT_TRUE(dev_comp_p0.len != dev_comp_p128.len);
LOG_INF("Start Node Composition Refresh procedure...\n");
struct bt_mesh_rpr_node srv = {
.addr = pb_remote_server_addr,
.net_idx = 0,
.ttl = 3,
};
/* Swap callback to catch when device reprovisioned. */
prov.node_added = prov_node_added_rpr;
ASSERT_OK(bt_mesh_reprovision_remote(&rpr_cli, &srv, pb_remote_server_addr, true));
ASSERT_OK(k_sem_take(&reprov_sem, K_SECONDS(20)));
/* Check that Composition Data Page 128 is now Page 0. */
net_buf_simple_reset(&dev_comp_p0);
ASSERT_OK(bt_mesh_cfg_cli_comp_data_get(0, pb_remote_server_addr, 0, &page, &dev_comp_p0));
ASSERT_EQUAL(0, page);
ASSERT_EQUAL(dev_comp_p0.len, dev_comp_p128.len);
if (memcmp(dev_comp_p0.data, dev_comp_p128.data, dev_comp_p0.len)) {
FAIL("Wrong composition data page 0");
}
net_buf_simple_reset(&dev_comp_p128);
ASSERT_OK(bt_mesh_cfg_cli_comp_data_get(0, pb_remote_server_addr, 128, &page,
&dev_comp_p128));
ASSERT_EQUAL(0, page);
ASSERT_EQUAL(dev_comp_p0.len, dev_comp_p128.len);
if (memcmp(dev_comp_p0.data, dev_comp_p128.data, dev_comp_p0.len)) {
FAIL("Wrong composition data page 128");
}
PASS();
}
/** @brief Test Node Composition Refresh procedure on Remote Provisioning client:
* - verify that Composition Data Page 0 is updated after reboot.
*/
static void test_provisioner_pb_remote_client_ncrp_second_time(void)
{
NET_BUF_SIMPLE_DEFINE(dev_comp_p0, BT_MESH_RX_SDU_MAX);
NET_BUF_SIMPLE_DEFINE(dev_comp_p128, BT_MESH_RX_SDU_MAX);
uint16_t pb_remote_server_addr = 0x0003;
uint8_t page;
int err;
k_sem_init(&prov_sem, 0, 1);
k_sem_init(&reprov_sem, 0, 1);
bt_mesh_device_setup(&prov, &rpr_cli_comp);
/* Check Composition Data Page 0 and 128. */
ASSERT_OK(bt_mesh_cfg_cli_comp_data_get(0, pb_remote_server_addr, 0, &page, &dev_comp_p0));
ASSERT_EQUAL(0, page);
ASSERT_OK(bt_mesh_cfg_cli_comp_data_get(0, pb_remote_server_addr, 128, &page,
&dev_comp_p128));
ASSERT_EQUAL(0, page);
ASSERT_TRUE(dev_comp_p0.len == dev_comp_p128.len);
LOG_INF("Start Node Composition Refresh procedure...\n");
struct bt_mesh_rpr_node srv = {
.addr = pb_remote_server_addr,
.net_idx = 0,
.ttl = 3,
};
/* Swap callback to catch when device reprovisioned. */
prov.node_added = prov_node_added_rpr;
ASSERT_OK(bt_mesh_reprovision_remote(&rpr_cli, &srv, pb_remote_server_addr, true));
err = k_sem_take(&reprov_sem, K_SECONDS(20));
ASSERT_EQUAL(-EAGAIN, err);
PASS();
}
/** @brief Test Node Composition Refresh procedure on Remote Provisioning server:
* - wait for being provisioned over PB-Adv,
* - prepare Composition Data Page 128.
*/
static void test_device_pb_remote_server_ncrp_prepare(void)
{
settings_test_backend_clear();
device_pb_remote_server_setup_unproved(&rpr_srv_comp);
LOG_INF("Preparing for Composition Data change");
bt_mesh_comp_change_prepare();
PASS();
}
/** @brief Test Node Composition Refresh procedure on Remote Provisioning server:
* - start device with new Composition Data
* - wait for being re-provisioned.
*/
static void test_device_pb_remote_server_ncrp(void)
{
device_pb_remote_server_setup_proved(&rpr_srv_comp_2_elem);
LOG_INF("Waiting for being re-provisioned.");
ASSERT_OK(k_sem_take(&reprov_sem, K_SECONDS(30)));
PASS();
}
/** @brief Test Node Composition Refresh procedure on Remote Provisioning server:
* - verify that Composition Data Page 128 is erased after being re-provisioned and rebooted.
*/
static void test_device_pb_remote_server_ncrp_second_time(void)
{
int err;
device_pb_remote_server_setup_proved(&rpr_srv_comp_2_elem);
LOG_INF("Wait to verify that node is not re-provisioned...");
err = k_sem_take(&reprov_sem, K_SECONDS(30));
ASSERT_EQUAL(-EAGAIN, err);
PASS();
}
#endif /* IS_RPR_PRESENT */
#define TEST_CASE(role, name, description) \
@ -993,10 +1217,10 @@ static const struct bst_test_instance test_connect[] = {
TEST_CASE(device, pb_adv_reprovision,
"Device: pb-adv provisioning, reprovision"),
#if IS_RPR_PRESENT
TEST_CASE(device, pb_remote_server,
"Device: pb-adv provisioning, running pb-remote server"),
TEST_CASE(device, pb_remote_server_unproved,
"Device: used for remote provisioning, starts unprovisioned"),
TEST_CASE(device, pb_remote_server_nppi_robustness,
"Device: pb-adv provisioning, running pb-remote server, NPPI robustness"),
"Device: pb-remote reprovisioning, NPPI robustness"),
#endif
TEST_CASE(provisioner, pb_adv_no_oob,
@ -1017,10 +1241,9 @@ static const struct bst_test_instance test_connect[] = {
"Provisioner: pb-adv provisioning, resetting and reprovisioning multiple times."),
#if IS_RPR_PRESENT
TEST_CASE(provisioner, pb_remote_client_reprovision,
"Provisioner: pb-remote client provisioning, resetting and reprovisioning "
"multiple times."),
"Provisioner: pb-remote provisioning, resetting and reprov-ing multiple times."),
TEST_CASE(provisioner, pb_remote_client_nppi_robustness,
"Provisioner: pb-remote client provisioning, NPPI robustness testing."),
"Provisioner: pb-remote provisioning, NPPI robustness."),
#endif
BSTEST_END_MARKER
@ -1031,3 +1254,34 @@ struct bst_test_list *test_provision_install(struct bst_test_list *tests)
tests = bst_add_tests(tests, test_connect);
return tests;
}
#if IS_RPR_PRESENT
static const struct bst_test_instance test_connect_pst[] = {
TEST_CASE(device, pb_remote_server_unproved,
"Device: used for remote provisioning, starts unprovisioned"),
TEST_CASE(device, pb_remote_server_proved,
"Device: used for remote provisioning, starts provisioned"),
TEST_CASE(device, pb_remote_server_ncrp_prepare,
"Device: NCRP test, prepares for Composition Data change."),
TEST_CASE(device, pb_remote_server_ncrp,
"Device: NCRP test, Composition Data change."),
TEST_CASE(device, pb_remote_server_ncrp_second_time,
"Device: NCRP test, Composition Data change after reboot."),
TEST_CASE(provisioner, pb_remote_client_ncrp_provision,
"Provisioner: NCRP test, devices provisioning."),
TEST_CASE(provisioner, pb_remote_client_ncrp,
"Provisioner: NCRP test, initiates Node Composition Refresh procedure."),
TEST_CASE(provisioner, pb_remote_client_ncrp_second_time,
"Provisioner: NCRP test, initiates NCR procedure the second time."),
BSTEST_END_MARKER
};
struct bst_test_list *test_provision_pst_install(struct bst_test_list *tests)
{
tests = bst_add_tests(tests, test_connect_pst);
return tests;
}
#endif /* IS_RPR_PRESENT */

View file

@ -16,5 +16,5 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh
conf=prj_mesh1d1_conf
RunTest mesh_provision_pb_remote_nppi_robustness \
prov_provisioner_pb_remote_client_nppi_robustness \
prov_device_pb_remote_server \
prov_device_pb_remote_server_unproved \
prov_device_pb_remote_server_nppi_robustness

View file

@ -0,0 +1,53 @@
#!/usr/bin/env bash
# Copyright 2022 Nordic Semiconductor
# SPDX-License-Identifier: Apache-2.0
source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh
# Test Node Composition Refresh procedure with persistence storage:
# 1. Prepare for Composition Data change.
# PB-Remote client (1st device):
# - provision the 2nd device over PB-Adv
# - provision the 3rd device over PB-Remote
# PB-Remote server (2nd device):
# - wait for being provisioned
# - run PB-Remote bearer
# PB-Remote server (3rd device):
# - wait for being provisioned
# - call bt_mesh_comp_change_prepare() to prepare for Composition Data change
# 2. Verify Node Composition Refresh procedure.
# PB-Remote client (1st device):
# - check that Composition Data pages 0 (old comp data) and 128 (new comp data) are different
# - run Node Composition Refresh procedure on the 3rd device
# - verify Composition Data pages 0 (new comp data) and 128 (same as page 0)
# PB-Remote server (3rd device):
# - start with a new Composition Data
# 3. Verify that old settings are removed on the 3rd device after Composition Data change.
# PB-Remote client (1st device):
# - run Node Composition Refresh procedure again and expect it to fail
# PB-Remote server (3rd device):
# - verify that the device is not re-provisioned again.
# Step 1
conf=prj_mesh1d1_conf
overlay=overlay_pst_conf
RunTest mesh_provision_pst_pb_remote_ncrp \
prov_provisioner_pb_remote_client_ncrp_provision \
prov_device_pb_remote_server_unproved \
prov_device_pb_remote_server_ncrp_prepare
# Step 2
conf=prj_mesh1d1_conf
overlay=overlay_pst_conf
RunTest mesh_provision_pst_pb_remote_ncrp \
prov_provisioner_pb_remote_client_ncrp \
prov_device_pb_remote_server_proved \
prov_device_pb_remote_server_ncrp
# Step 3
conf=prj_mesh1d1_conf
overlay=overlay_pst_conf
RunTest mesh_provision_pst_pb_remote_ncrp \
prov_provisioner_pb_remote_client_ncrp_second_time \
prov_device_pb_remote_server_proved \
prov_device_pb_remote_server_ncrp_second_time

View file

@ -15,5 +15,5 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh
conf=prj_mesh1d1_conf
RunTest mesh_provision_pb_remote_reprovision \
prov_provisioner_pb_remote_client_reprovision \
prov_device_pb_remote_server \
prov_device_pb_remote_server_unproved \
prov_device_pb_adv_reprovision