Bluetooth: Mesh: Fixed issue with RPR server and client.
Fixed issue when reprovisioning is done on a device with both RPR client and server on the same device. Signed-off-by: Ingar Kulbrandstad <ingar.kulbrandstad@nordicsemi.no>
This commit is contained in:
parent
e04c963d9c
commit
a5d15ec017
3 changed files with 444 additions and 123 deletions
|
@ -857,6 +857,72 @@ int bt_mesh_pb_remote_open(struct bt_mesh_rpr_cli *cli,
|
|||
return link_open(uuid, &pb_remote_cli, net_idx, addr, 0, &ctx, 0);
|
||||
}
|
||||
|
||||
/* Remote Provision done where client and server is on same node, skip open link
|
||||
* and sending of reprovision message, just execute reprovisioning on it self.
|
||||
*/
|
||||
static int reprovision_local_client_server(uint16_t addr)
|
||||
{
|
||||
int err;
|
||||
const uint8_t *pub_key;
|
||||
const uint8_t *priv_key = NULL;
|
||||
|
||||
if (atomic_test_and_set_bit(bt_mesh_prov_link.flags, LINK_ACTIVE)) {
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
LOG_DBG("net_idx %u iv_index 0x%08x, addr 0x%04x",
|
||||
prov_device.node->net_idx, bt_mesh_cdb.iv_index, addr);
|
||||
|
||||
atomic_set_bit(bt_mesh_prov_link.flags, REPROVISION);
|
||||
atomic_set_bit(bt_mesh_prov_link.flags, PROVISIONER);
|
||||
bt_mesh_prov_link.addr = addr;
|
||||
bt_mesh_prov_link.bearer = &pb_remote_cli;
|
||||
bt_mesh_prov_link.role = &role_provisioner;
|
||||
prov_device.net_idx = prov_device.node->net_idx;
|
||||
prov_device.attention_duration = 0;
|
||||
|
||||
if (IS_ENABLED(CONFIG_BT_MESH_PROV_OOB_PUBLIC_KEY) &&
|
||||
bt_mesh_prov->public_key_be && bt_mesh_prov->private_key_be) {
|
||||
LOG_DBG("Use OOB Public and Private key");
|
||||
pub_key = bt_mesh_prov->public_key_be;
|
||||
priv_key = bt_mesh_prov->private_key_be;
|
||||
} else {
|
||||
pub_key = bt_mesh_pub_key_get();
|
||||
}
|
||||
|
||||
if (!pub_key) {
|
||||
LOG_ERR("No public key available");
|
||||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
if (bt_mesh_dhkey_gen(pub_key, priv_key, bt_mesh_prov_link.dhkey)) {
|
||||
LOG_ERR("Failed to generate DHKey");
|
||||
return -ENOEXEC;
|
||||
}
|
||||
LOG_DBG("DHkey: %s", bt_hex(bt_mesh_prov_link.dhkey, DH_KEY_SIZE));
|
||||
|
||||
err = bt_mesh_dev_key(bt_mesh_prov_link.dhkey,
|
||||
bt_mesh_prov_link.prov_salt, prov_device.new_dev_key);
|
||||
if (err) {
|
||||
LOG_ERR("Unable to generate device key");
|
||||
return err;
|
||||
}
|
||||
|
||||
bt_mesh_dev_key_cand(prov_device.new_dev_key);
|
||||
/* Mark the link that was never opened as closed. */
|
||||
atomic_set_bit(bt_mesh_prov_link.flags, COMPLETE);
|
||||
bt_mesh_reprovision(addr);
|
||||
bt_mesh_dev_key_cand_activate();
|
||||
|
||||
if (bt_mesh_prov->reprovisioned) {
|
||||
LOG_DBG("Application reprovisioned callback 0x%04x", bt_mesh_primary_addr());
|
||||
bt_mesh_prov->reprovisioned(bt_mesh_primary_addr());
|
||||
}
|
||||
|
||||
prov_link_closed(PROV_BEARER_LINK_STATUS_SUCCESS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bt_mesh_pb_remote_open_node(struct bt_mesh_rpr_cli *cli,
|
||||
struct bt_mesh_rpr_node *srv, uint16_t addr,
|
||||
bool composition_change)
|
||||
|
@ -877,6 +943,11 @@ int bt_mesh_pb_remote_open_node(struct bt_mesh_rpr_cli *cli,
|
|||
return -ENOENT;
|
||||
}
|
||||
|
||||
/* Check if server is on same device as client */
|
||||
if (IS_ENABLED(CONFIG_BT_MESH_RPR_SRV) && bt_mesh_has_addr(srv->addr)) {
|
||||
return reprovision_local_client_server(addr);
|
||||
}
|
||||
|
||||
return link_open(NULL, &pb_remote_cli, prov_device.node->net_idx, addr,
|
||||
0, &ctx, 0);
|
||||
}
|
||||
|
|
|
@ -139,6 +139,19 @@ static const struct bt_mesh_comp rpr_srv_comp = {
|
|||
.elem_count = 1,
|
||||
};
|
||||
|
||||
static const struct bt_mesh_comp rpr_cli_srv_comp = {
|
||||
.elem =
|
||||
(struct bt_mesh_elem[]){
|
||||
BT_MESH_ELEM(1,
|
||||
MODEL_LIST(BT_MESH_MODEL_CFG_SRV,
|
||||
BT_MESH_MODEL_CFG_CLI(&(struct bt_mesh_cfg_cli){}),
|
||||
BT_MESH_MODEL_RPR_CLI(&rpr_cli),
|
||||
BT_MESH_MODEL_RPR_SRV),
|
||||
BT_MESH_MODEL_NONE),
|
||||
},
|
||||
.elem_count = 1,
|
||||
};
|
||||
|
||||
static int mock_pdu_send(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx,
|
||||
struct net_buf_simple *buf)
|
||||
{
|
||||
|
@ -1072,52 +1085,16 @@ static void test_provisioner_pb_remote_client_provision_timeout(void)
|
|||
PASS();
|
||||
}
|
||||
|
||||
/** @brief Verify robustness of NPPI procedures on a RPR Client by running Device Key Refresh,
|
||||
* Node Composition Refresh and Node Address Refresh procedures.
|
||||
*/
|
||||
static void test_provisioner_pb_remote_client_nppi_robustness(void)
|
||||
static void reprovision_remote_devkey_client(struct bt_mesh_rpr_node *srv,
|
||||
struct bt_mesh_cdb_node *node)
|
||||
{
|
||||
NET_BUF_SIMPLE_DEFINE(dev_comp, BT_MESH_RX_SDU_MAX);
|
||||
NET_BUF_SIMPLE_DEFINE(new_dev_comp, BT_MESH_RX_SDU_MAX);
|
||||
uint8_t page;
|
||||
uint16_t pb_remote_server_addr;
|
||||
uint8_t status;
|
||||
struct bt_mesh_cdb_node *node;
|
||||
uint8_t prev_node_dev_key[16];
|
||||
|
||||
provisioner_pb_remote_client_setup();
|
||||
|
||||
/* Provision the 2nd device over PB-Adv. */
|
||||
ASSERT_OK(provision_adv(1, &pb_remote_server_addr));
|
||||
|
||||
/* Provision a remote device with RPR Server. */
|
||||
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, current_dev_addr, 0, 0, test_app_key, &status));
|
||||
ASSERT_OK(status);
|
||||
|
||||
/* Swap callback to catch when device reprovisioned. */
|
||||
prov.node_added = prov_node_added_rpr;
|
||||
|
||||
/* Store initial Composition Data Page 0. */
|
||||
ASSERT_OK(bt_mesh_cfg_cli_comp_data_get(0, current_dev_addr, 0, &page, &dev_comp));
|
||||
|
||||
node = bt_mesh_cdb_node_get(current_dev_addr);
|
||||
ASSERT_TRUE(node);
|
||||
ASSERT_OK_MSG(bt_mesh_cdb_node_key_export(node, prev_node_dev_key),
|
||||
"Can't export device key from cdb");
|
||||
|
||||
LOG_INF("Testing DevKey refresh...");
|
||||
for (int i = 0; i < PROV_REPROV_COUNT; i++) {
|
||||
LOG_INF("Refreshing device key #%d...\n", i);
|
||||
bt_mesh_reprovision_remote(&rpr_cli, &srv, current_dev_addr, false);
|
||||
bt_mesh_reprovision_remote(&rpr_cli, srv, current_dev_addr, false);
|
||||
|
||||
ASSERT_OK(k_sem_take(&reprov_sem, K_SECONDS(20)));
|
||||
|
||||
|
@ -1133,12 +1110,20 @@ static void test_provisioner_pb_remote_client_nppi_robustness(void)
|
|||
|
||||
/* Let RPR Server verify Device Key. */
|
||||
k_sleep(K_SECONDS(2));
|
||||
}
|
||||
}
|
||||
|
||||
LOG_INF("Testing Composition Data refresh...");
|
||||
for (int i = 0; i < PROV_REPROV_COUNT; i++) {
|
||||
LOG_INF("Changing Composition Data #%d...\n", i);
|
||||
bt_mesh_reprovision_remote(&rpr_cli, &srv, current_dev_addr, true);
|
||||
static void reprovision_remote_comp_data_client(struct bt_mesh_rpr_node *srv,
|
||||
struct bt_mesh_cdb_node *node,
|
||||
struct net_buf_simple *dev_comp)
|
||||
{
|
||||
NET_BUF_SIMPLE_DEFINE(new_dev_comp, BT_MESH_RX_SDU_MAX);
|
||||
uint8_t prev_node_dev_key[16];
|
||||
uint8_t page;
|
||||
|
||||
ASSERT_OK_MSG(bt_mesh_cdb_node_key_export(node, prev_node_dev_key),
|
||||
"Can't export device key from cdb");
|
||||
|
||||
bt_mesh_reprovision_remote(&rpr_cli, srv, current_dev_addr, true);
|
||||
|
||||
ASSERT_OK(k_sem_take(&reprov_sem, K_SECONDS(20)));
|
||||
|
||||
|
@ -1151,25 +1136,32 @@ static void test_provisioner_pb_remote_client_nppi_robustness(void)
|
|||
net_buf_simple_reset(&new_dev_comp);
|
||||
ASSERT_OK(bt_mesh_cfg_cli_comp_data_get(0, current_dev_addr, 0, &page,
|
||||
&new_dev_comp));
|
||||
|
||||
ASSERT_EQUAL(0, page);
|
||||
ASSERT_EQUAL(dev_comp.len, new_dev_comp.len);
|
||||
if (memcmp(dev_comp.data, new_dev_comp.data, dev_comp.len)) {
|
||||
ASSERT_EQUAL(dev_comp->len, new_dev_comp.len);
|
||||
if (memcmp(dev_comp->data, new_dev_comp.data, dev_comp->len)) {
|
||||
FAIL("Wrong composition data page 0");
|
||||
}
|
||||
|
||||
/* Let RPR Server verify Device Key. */
|
||||
k_sleep(K_SECONDS(2));
|
||||
}
|
||||
}
|
||||
|
||||
LOG_INF("Testing address refresh...");
|
||||
for (int i = 0; i < PROV_REPROV_COUNT; i++) {
|
||||
LOG_INF("Changing address #%d...\n", i);
|
||||
bt_mesh_reprovision_remote(&rpr_cli, &srv, current_dev_addr + 1, false);
|
||||
static void reprovision_remote_address_client(struct bt_mesh_rpr_node *srv,
|
||||
struct bt_mesh_cdb_node *node)
|
||||
{
|
||||
uint8_t status;
|
||||
uint8_t prev_node_dev_key[16];
|
||||
|
||||
ASSERT_OK_MSG(bt_mesh_cdb_node_key_export(node, prev_node_dev_key),
|
||||
"Can't export device key from cdb");
|
||||
|
||||
bt_mesh_reprovision_remote(&rpr_cli, srv, current_dev_addr + 1, false);
|
||||
|
||||
ASSERT_OK(k_sem_take(&reprov_sem, K_SECONDS(20)));
|
||||
|
||||
current_dev_addr++;
|
||||
srv.addr++;
|
||||
srv->addr++;
|
||||
|
||||
/* Check that device doesn't respond to old address with old and new device key. */
|
||||
struct bt_mesh_cdb_node *prev_node;
|
||||
|
@ -1201,6 +1193,63 @@ static void test_provisioner_pb_remote_client_nppi_robustness(void)
|
|||
|
||||
/* Let RPR Server verify Device Key. */
|
||||
k_sleep(K_SECONDS(2));
|
||||
|
||||
}
|
||||
|
||||
/** @brief Verify robustness of NPPI procedures on a RPR Client by running Device Key Refresh,
|
||||
* Node Composition Refresh and Node Address Refresh procedures.
|
||||
*/
|
||||
static void test_provisioner_pb_remote_client_nppi_robustness(void)
|
||||
{
|
||||
NET_BUF_SIMPLE_DEFINE(dev_comp, BT_MESH_RX_SDU_MAX);
|
||||
uint8_t page;
|
||||
uint16_t pb_remote_server_addr;
|
||||
uint8_t status;
|
||||
struct bt_mesh_cdb_node *node;
|
||||
|
||||
provisioner_pb_remote_client_setup();
|
||||
|
||||
/* Provision the 2nd device over PB-Adv. */
|
||||
ASSERT_OK(provision_adv(1, &pb_remote_server_addr));
|
||||
|
||||
/* Provision a remote device with RPR Server. */
|
||||
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, current_dev_addr, 0, 0, test_app_key, &status));
|
||||
ASSERT_OK(status);
|
||||
|
||||
/* Swap callback to catch when device reprovisioned. */
|
||||
prov.node_added = prov_node_added_rpr;
|
||||
|
||||
/* Store initial Composition Data Page 0. */
|
||||
ASSERT_OK(bt_mesh_cfg_cli_comp_data_get(0, current_dev_addr, 0, &page, &dev_comp));
|
||||
|
||||
node = bt_mesh_cdb_node_get(current_dev_addr);
|
||||
ASSERT_TRUE(node);
|
||||
|
||||
LOG_INF("Testing DevKey refresh...");
|
||||
for (int i = 0; i < PROV_REPROV_COUNT; i++) {
|
||||
LOG_INF("Refreshing device key #%d...\n", i);
|
||||
reprovision_remote_devkey_client(&srv, node);
|
||||
}
|
||||
|
||||
LOG_INF("Testing Composition Data refresh...");
|
||||
for (int i = 0; i < PROV_REPROV_COUNT; i++) {
|
||||
LOG_INF("Changing Composition Data #%d...\n", i);
|
||||
reprovision_remote_comp_data_client(&srv, node, &dev_comp);
|
||||
}
|
||||
|
||||
LOG_INF("Testing address refresh...");
|
||||
for (int i = 0; i < PROV_REPROV_COUNT; i++) {
|
||||
LOG_INF("Changing address #%d...\n", i);
|
||||
reprovision_remote_address_client(&srv, node);
|
||||
}
|
||||
|
||||
PASS();
|
||||
|
@ -1240,13 +1289,78 @@ static void test_device_pb_remote_server_proved(void)
|
|||
PASS();
|
||||
}
|
||||
|
||||
static void reprovision_remote_devkey_server(const uint16_t initial_addr)
|
||||
{
|
||||
uint8_t prev_dev_key[16];
|
||||
uint8_t dev_key[16];
|
||||
|
||||
ASSERT_OK(bt_mesh_key_export(prev_dev_key, &bt_mesh.dev_key));
|
||||
|
||||
ASSERT_OK(k_sem_take(&reprov_sem, K_SECONDS(30)));
|
||||
ASSERT_EQUAL(initial_addr, bt_mesh_primary_addr());
|
||||
|
||||
/* Let Configuration Client activate the new Device Key and verify that it has
|
||||
* been changed.
|
||||
*/
|
||||
k_sleep(K_SECONDS(2));
|
||||
ASSERT_OK(bt_mesh_key_export(dev_key, &bt_mesh.dev_key));
|
||||
ASSERT_TRUE(memcmp(&prev_dev_key, dev_key, sizeof(dev_key)));
|
||||
}
|
||||
|
||||
static void reprovision_remote_comp_data_server(const uint16_t initial_addr)
|
||||
{
|
||||
u_int8_t prev_dev_key[16];
|
||||
u_int8_t dev_key[16];
|
||||
|
||||
/* The RPR Server won't let to run Node Composition Refresh procedure without first
|
||||
* setting the BT_MESH_COMP_DIRTY flag. The flag is set on a boot if there is a
|
||||
* "bt/mesh/cmp" entry in settings. The entry is added by the
|
||||
* `bt_mesh_comp_change_prepare() call. The test suite is not compiled
|
||||
* with CONFIG_BT_SETTINGS, so the flag will never be set. Since the purpose of the
|
||||
* test is to check RPR Server behavior, but not the actual swap of the Composition
|
||||
* Data, the flag is toggled directly from the test.
|
||||
*/
|
||||
atomic_set_bit(bt_mesh.flags, BT_MESH_COMP_DIRTY);
|
||||
ASSERT_OK(bt_mesh_key_export(prev_dev_key, &bt_mesh.dev_key));
|
||||
|
||||
ASSERT_OK(k_sem_take(&reprov_sem, K_SECONDS(30)));
|
||||
|
||||
/* Drop the flag manually as CONFIG_BT_SETTINGS is not enabled. */
|
||||
atomic_clear_bit(bt_mesh.flags, BT_MESH_COMP_DIRTY);
|
||||
|
||||
ASSERT_EQUAL(initial_addr, bt_mesh_primary_addr());
|
||||
|
||||
/* Let Configuration Client activate the new Device Key and verify that it has
|
||||
* been changed.
|
||||
*/
|
||||
k_sleep(K_SECONDS(2));
|
||||
ASSERT_OK(bt_mesh_key_export(dev_key, &bt_mesh.dev_key));
|
||||
ASSERT_TRUE(memcmp(prev_dev_key, dev_key, sizeof(dev_key)));
|
||||
}
|
||||
|
||||
static void reprovision_remote_address_server(const uint16_t initial_addr)
|
||||
{
|
||||
uint8_t prev_dev_key[16];
|
||||
uint8_t dev_key[16];
|
||||
|
||||
ASSERT_OK(bt_mesh_key_export(prev_dev_key, &bt_mesh.dev_key));
|
||||
|
||||
ASSERT_OK(k_sem_take(&reprov_sem, K_SECONDS(30)));
|
||||
ASSERT_EQUAL(initial_addr + 1, bt_mesh_primary_addr());
|
||||
|
||||
/* Let Configuration Client activate the new Device Key and verify that it has
|
||||
* been changed.
|
||||
*/
|
||||
k_sleep(K_SECONDS(2));
|
||||
ASSERT_OK(bt_mesh_key_export(dev_key, &bt_mesh.dev_key));
|
||||
ASSERT_TRUE(memcmp(prev_dev_key, dev_key, sizeof(dev_key)));
|
||||
}
|
||||
|
||||
/** @brief Verify robustness of NPPI procedures on a RPR Server by running Device Key Refresh,
|
||||
* Node Composition Refresh and Node Address Refresh procedures multiple times each.
|
||||
*/
|
||||
static void test_device_pb_remote_server_nppi_robustness(void)
|
||||
{
|
||||
struct bt_mesh_key prev_dev_key;
|
||||
|
||||
k_sem_init(&prov_sem, 0, 1);
|
||||
k_sem_init(&reprov_sem, 0, 1);
|
||||
|
||||
|
@ -1259,65 +1373,25 @@ static void test_device_pb_remote_server_nppi_robustness(void)
|
|||
ASSERT_OK(k_sem_take(&prov_sem, K_SECONDS(20)));
|
||||
const uint16_t initial_addr = bt_mesh_primary_addr();
|
||||
|
||||
memcpy(&prev_dev_key, &bt_mesh.dev_key, sizeof(struct bt_mesh_key));
|
||||
|
||||
LOG_INF("Enabling PB-Remote server");
|
||||
ASSERT_OK(bt_mesh_prov_enable(BT_MESH_PROV_REMOTE));
|
||||
|
||||
/* Test Device Key Refresh procedure robustness. */
|
||||
for (int i = 0; i < PROV_REPROV_COUNT; i++) {
|
||||
LOG_INF("Devkey refresh loop #%d, waiting for being reprov ...\n", i);
|
||||
ASSERT_OK(k_sem_take(&reprov_sem, K_SECONDS(30)));
|
||||
ASSERT_EQUAL(initial_addr, bt_mesh_primary_addr());
|
||||
|
||||
/* Let Configuration Client activate the new Device Key and verify that it has
|
||||
* been changed.
|
||||
*/
|
||||
k_sleep(K_SECONDS(2));
|
||||
ASSERT_TRUE(memcmp(&prev_dev_key, &bt_mesh.dev_key, sizeof(struct bt_mesh_key)));
|
||||
memcpy(&prev_dev_key, &bt_mesh.dev_key, sizeof(struct bt_mesh_key));
|
||||
reprovision_remote_devkey_server(initial_addr);
|
||||
}
|
||||
|
||||
/* Test Node Composition Refresh procedure robustness. */
|
||||
for (int i = 0; i < PROV_REPROV_COUNT; i++) {
|
||||
/* The RPR Server won't let to run Node Composition Refresh procedure without first
|
||||
* setting the BT_MESH_COMP_DIRTY flag. The flag is set on a boot if there is a
|
||||
* "bt/mesh/cmp" entry in settings. The entry is added by the
|
||||
* `bt_mesh_comp_change_prepare() call. The test suite is not compiled
|
||||
* with CONFIG_BT_SETTINGS, so the flag will never be set. Since the purpose of the
|
||||
* test is to check RPR Server behavior, but not the actual swap of the Composition
|
||||
* Data, the flag is toggled directly from the test.
|
||||
*/
|
||||
atomic_set_bit(bt_mesh.flags, BT_MESH_COMP_DIRTY);
|
||||
|
||||
LOG_INF("Composition data refresh loop #%d, waiting for being reprov ...\n", i);
|
||||
ASSERT_OK(k_sem_take(&reprov_sem, K_SECONDS(30)));
|
||||
|
||||
/* Drop the flag manually as CONFIG_BT_SETTINGS is not enabled. */
|
||||
atomic_clear_bit(bt_mesh.flags, BT_MESH_COMP_DIRTY);
|
||||
|
||||
ASSERT_EQUAL(initial_addr, bt_mesh_primary_addr());
|
||||
|
||||
/* Let Configuration Client activate the new Device Key and verify that it has
|
||||
* been changed.
|
||||
*/
|
||||
k_sleep(K_SECONDS(2));
|
||||
ASSERT_TRUE(memcmp(&prev_dev_key, &bt_mesh.dev_key, sizeof(struct bt_mesh_key)));
|
||||
memcpy(&prev_dev_key, &bt_mesh.dev_key, sizeof(struct bt_mesh_key));
|
||||
reprovision_remote_comp_data_server(initial_addr);
|
||||
}
|
||||
|
||||
/* Node Address Refresh robustness. */
|
||||
for (int i = 0; i < PROV_REPROV_COUNT; i++) {
|
||||
LOG_INF("Address refresh loop #%d, waiting for being reprov ...\n", i);
|
||||
ASSERT_OK(k_sem_take(&reprov_sem, K_SECONDS(30)));
|
||||
ASSERT_EQUAL(initial_addr + 1 + i, bt_mesh_primary_addr());
|
||||
|
||||
/* Let Configuration Client activate the new Device Key and verify that it has
|
||||
* been changed.
|
||||
*/
|
||||
k_sleep(K_SECONDS(2));
|
||||
ASSERT_TRUE(memcmp(&prev_dev_key, &bt_mesh.dev_key, sizeof(struct bt_mesh_key)));
|
||||
memcpy(&prev_dev_key, &bt_mesh.dev_key, sizeof(struct bt_mesh_key));
|
||||
reprovision_remote_address_server(initial_addr+i);
|
||||
}
|
||||
|
||||
PASS();
|
||||
|
@ -1354,6 +1428,146 @@ static void test_provisioner_pb_remote_client_ncrp_provision(void)
|
|||
PASS();
|
||||
}
|
||||
|
||||
/** @brief A device running a Remote Provisioning client and server that is used to reprovision
|
||||
* another device and it self with the client.
|
||||
*/
|
||||
static void test_device_pb_remote_client_server_same_dev(void)
|
||||
{
|
||||
NET_BUF_SIMPLE_DEFINE(dev_comp, BT_MESH_RX_SDU_MAX);
|
||||
uint8_t status;
|
||||
struct bt_mesh_cdb_node *node;
|
||||
uint8_t page;
|
||||
uint8_t prev_dev_key[16];
|
||||
uint16_t test_vector[] = { 0x0002, 0x0001 };
|
||||
|
||||
k_sem_init(&prov_sem, 0, 1);
|
||||
k_sem_init(&reprov_sem, 0, 1);
|
||||
|
||||
bt_mesh_device_setup(&prov, &rpr_cli_srv_comp);
|
||||
|
||||
ASSERT_OK(bt_mesh_cdb_create(test_net_key));
|
||||
ASSERT_OK(bt_mesh_provision(test_net_key, 0, 0, 0, 0x0001, dev_key));
|
||||
|
||||
LOG_INF("Enabling PB-Remote server");
|
||||
ASSERT_OK(bt_mesh_prov_enable(BT_MESH_PROV_REMOTE));
|
||||
|
||||
/* Provision a remote device with RPR Client and Server with local RPR Server. */
|
||||
current_dev_addr = 0x0001;
|
||||
struct bt_mesh_rpr_node srv = {
|
||||
.addr = current_dev_addr,
|
||||
.net_idx = 0,
|
||||
.ttl = 3,
|
||||
};
|
||||
|
||||
LOG_INF("Provisioner prov, waiting for prov ...\n");
|
||||
ASSERT_OK(provision_remote(&srv, 1, &srv.addr));
|
||||
|
||||
ASSERT_OK(k_sem_take(&prov_sem, K_SECONDS(20)));
|
||||
|
||||
/* Check device key by adding bt_mesh_reprovision_remote appkey. */
|
||||
ASSERT_OK(bt_mesh_cfg_cli_app_key_add(0, current_dev_addr, 0, 0, test_app_key, &status));
|
||||
ASSERT_OK(status);
|
||||
|
||||
/* Swap callback to catch when device reprovisioned. */
|
||||
prov.node_added = prov_node_added_rpr;
|
||||
|
||||
/* Reprovision a device with both RPR Client and Server. */
|
||||
for (int i = 0; i < ARRAY_SIZE(test_vector); i++) {
|
||||
current_dev_addr = test_vector[i];
|
||||
srv.addr = current_dev_addr;
|
||||
bool self_reprov = (bool)(current_dev_addr == bt_mesh_primary_addr());
|
||||
|
||||
/* Store initial Composition Data Page 0. */
|
||||
net_buf_simple_reset(&dev_comp);
|
||||
ASSERT_OK(bt_mesh_cfg_cli_comp_data_get(0, current_dev_addr, 0, &page, &dev_comp));
|
||||
|
||||
node = bt_mesh_cdb_node_get(current_dev_addr);
|
||||
ASSERT_TRUE(node);
|
||||
|
||||
LOG_INF("Refreshing 0x%04x device key ...\n", srv.addr);
|
||||
ASSERT_OK(bt_mesh_key_export(prev_dev_key, &bt_mesh.dev_key));
|
||||
reprovision_remote_devkey_client(&srv, node);
|
||||
if (self_reprov) {
|
||||
uint8_t dev_key[16];
|
||||
|
||||
ASSERT_EQUAL(current_dev_addr, bt_mesh_primary_addr());
|
||||
|
||||
/* Let Configuration Client activate the new Device Key
|
||||
* and verify that it has been changed.
|
||||
*/
|
||||
ASSERT_OK(bt_mesh_key_export(dev_key, &bt_mesh.dev_key));
|
||||
ASSERT_TRUE(memcmp(prev_dev_key, dev_key, sizeof(dev_key)));
|
||||
}
|
||||
|
||||
LOG_INF("Changing 0x%04x Composition Data ...\n", srv.addr);
|
||||
ASSERT_OK(bt_mesh_key_export(prev_dev_key, &bt_mesh.dev_key));
|
||||
reprovision_remote_comp_data_client(&srv, node, &dev_comp);
|
||||
if (self_reprov) {
|
||||
uint8_t dev_key[16];
|
||||
|
||||
ASSERT_EQUAL(current_dev_addr, bt_mesh_primary_addr());
|
||||
|
||||
/* Let Configuration Client activate the new Device Key
|
||||
* and verify that it has been changed.
|
||||
*/
|
||||
ASSERT_OK(bt_mesh_key_export(dev_key, &bt_mesh.dev_key));
|
||||
ASSERT_TRUE(memcmp(prev_dev_key, dev_key, sizeof(struct bt_mesh_key)));
|
||||
}
|
||||
|
||||
LOG_INF("Changing 0x%04x address ...\n", srv.addr);
|
||||
ASSERT_OK(bt_mesh_key_export(prev_dev_key, &bt_mesh.dev_key));
|
||||
reprovision_remote_address_client(&srv, node);
|
||||
if (self_reprov) {
|
||||
uint8_t dev_key[16];
|
||||
|
||||
ASSERT_EQUAL(current_dev_addr, bt_mesh_primary_addr());
|
||||
|
||||
/* Let Configuration Client activate the new Device Key
|
||||
* and verify that it has been changed.
|
||||
*/
|
||||
ASSERT_OK(bt_mesh_key_export(dev_key, &bt_mesh.dev_key));
|
||||
ASSERT_TRUE(memcmp(prev_dev_key, dev_key, sizeof(dev_key)));
|
||||
}
|
||||
}
|
||||
|
||||
PASS();
|
||||
}
|
||||
|
||||
/** @brief Verify that the Remote Provisioning client and server is able to be reprovision
|
||||
* by another device with a Remote Provisioning client and server.
|
||||
*/
|
||||
static void test_device_pb_remote_server_same_dev(void)
|
||||
{
|
||||
k_sem_init(&prov_sem, 0, 1);
|
||||
k_sem_init(&reprov_sem, 0, 1);
|
||||
|
||||
bt_mesh_device_setup(&prov, &rpr_cli_srv_comp);
|
||||
|
||||
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)));
|
||||
|
||||
LOG_INF("Enabling PB-Remote server");
|
||||
ASSERT_OK(bt_mesh_prov_enable(BT_MESH_PROV_REMOTE));
|
||||
|
||||
/* Swap callback to catch when device reprovisioned. */
|
||||
prov.node_added = prov_node_added_rpr;
|
||||
|
||||
const uint16_t initial_addr = bt_mesh_primary_addr();
|
||||
|
||||
LOG_INF("Devkey refresh, waiting for being reprov ...\n");
|
||||
reprovision_remote_devkey_server(initial_addr);
|
||||
|
||||
LOG_INF("Composition data refresh, waiting for being reprov ...\n");
|
||||
reprovision_remote_comp_data_server(initial_addr);
|
||||
|
||||
LOG_INF("Address refresh, waiting for being reprov ...\n");
|
||||
reprovision_remote_address_server(initial_addr);
|
||||
|
||||
PASS();
|
||||
}
|
||||
|
||||
static void comp_data_get(uint16_t server_addr, uint8_t page, struct net_buf_simple *comp)
|
||||
{
|
||||
uint8_t page_rsp;
|
||||
|
@ -1573,6 +1787,10 @@ static const struct bst_test_instance test_connect[] = {
|
|||
"Device: pb-remote reprovisioning, NPPI robustness"),
|
||||
TEST_CASE(device, pb_remote_server_unproved_unresponsive,
|
||||
"Device: used for remote provisioning, starts unprovisioned, stops responding"),
|
||||
TEST_CASE(device, pb_remote_client_server_same_dev,
|
||||
"Device: used for remote provisioning, with both client and server"),
|
||||
TEST_CASE(device, pb_remote_server_same_dev,
|
||||
"Device: used for remote reprovisioning, with both client and server"),
|
||||
#endif
|
||||
|
||||
TEST_CASE(provisioner, pb_adv_no_oob,
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
#!/usr/bin/env bash
|
||||
# Copyright 2023 Nordic Semiconductor
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh
|
||||
|
||||
# Test a node re-provisioning through Remote Provisioning models. Procedure:
|
||||
# 1. Device (prov_device_pb_remote_client_server_same_dev) provisions it self
|
||||
# and start scanning for an upprovisioned device, and provisions the the
|
||||
# second device (prov_device_pb_remote_server_same_dev) with local RPR server.
|
||||
# 2. The first device (prov_device_pb_remote_client_server_same_dev) execute
|
||||
# device key refresh procedure the second device (prov_device_pb_remote_server_same_dev).
|
||||
# 3. The first device (prov_device_pb_remote_client_server_same_dev) execute
|
||||
# composition refresh procedure the second device (prov_device_pb_remote_server_same_dev).
|
||||
# 4. The first device (prov_device_pb_remote_client_server_same_dev) execute
|
||||
# address refresh procedure the second device (prov_device_pb_remote_server_same_dev).
|
||||
# 5. The first device (prov_device_pb_remote_client_server_same_dev) execute
|
||||
# device key refresh procedure on it self with local RPR client and server.
|
||||
# 6. The first device (prov_device_pb_remote_client_server_same_dev) execute
|
||||
# composition refresh procedure on it self with local RPR client and server.
|
||||
# 7. The first device (prov_device_pb_remote_client_server_same_dev) execute
|
||||
# address refresh procedure on it self with local RPR client and server.
|
||||
conf=prj_mesh1d1_conf
|
||||
RunTest mesh_prov_pb_remote_client_server_same_dev \
|
||||
prov_device_pb_remote_client_server_same_dev \
|
||||
prov_device_pb_remote_server_same_dev
|
||||
|
||||
conf=prj_mesh1d1_conf
|
||||
overlay=overlay_psa_conf
|
||||
RunTest mesh_prov_pb_remote_client_server_same_dev \
|
||||
prov_device_pb_remote_client_server_same_dev \
|
||||
prov_device_pb_remote_server_same_dev
|
Loading…
Add table
Add a link
Reference in a new issue