Skip to content

Commit

Permalink
Bluetooth: Mesh: Test provisioning multiple devices
Browse files Browse the repository at this point in the history
Adds a BabbleSim test for provisioning multiple devices in a row. This
scenario had a regression in #33782, which is fixed in #35405.

Signed-off-by: Trond Einar Snekvik <Trond.Einar.Snekvik@nordicsemi.no>
  • Loading branch information
trond-snekvik authored and jhedberg committed Jul 13, 2021
1 parent 4fcec51 commit e6000e6
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 11 deletions.
2 changes: 1 addition & 1 deletion tests/bluetooth/bsim_bt/bsim_test_mesh/prj.conf
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,6 @@ CONFIG_BT_MESH_PB_ADV=y
CONFIG_BT_MESH_PROVISIONER=y
CONFIG_BT_MESH_PROV_DEVICE=y
CONFIG_BT_MESH_CDB=y
CONFIG_BT_MESH_CDB_NODE_COUNT=3
CONFIG_BT_MESH_CDB_NODE_COUNT=4

CONFIG_BT_MESH_DEBUG=y
69 changes: 59 additions & 10 deletions tests/bluetooth/bsim_bt/bsim_test_mesh/src/test_provision.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,43 +17,67 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME);
* Tests both the provisioner and device role in various scenarios.
*/

#define PROV_MULTI_COUNT 3

enum test_flags {
IS_PROVISIONER,

TEST_FLAGS,
};

static ATOMIC_DEFINE(flags, TEST_FLAGS);
extern const struct bt_mesh_comp comp;
extern const uint8_t test_net_key[16];
extern uint global_device_nbr;

/* Timeout semaphore */
static struct k_sem prov_sem;
static uint16_t prov_addr = 0x0002;
static const uint8_t dev_key[16] = { 0x01, 0x02, 0x03, 0x04, 0x05 };
static uint8_t dev_uuid[16] = { 0x6c, 0x69, 0x6e, 0x67, 0x61, 0x6f };

#define WAIT_TIME 60 /*seconds*/

static void test_device_init(void)
{
/* Ensure that the UUID is unique: */
dev_uuid[6] = '0' + global_device_nbr;

bt_mesh_test_cfg_set(NULL, WAIT_TIME);
}

static void test_provisioner_init(void)
{
atomic_set_bit(flags, IS_PROVISIONER);
bt_mesh_test_cfg_set(NULL, WAIT_TIME);
}

static void unprovisioned_beacon(uint8_t uuid[16],
bt_mesh_prov_oob_info_t oob_info,
uint32_t *uri_hash)
{
bt_mesh_provision_adv(uuid, 0, 0, 0);
if (!atomic_test_bit(flags, IS_PROVISIONER)) {
return;
}

bt_mesh_provision_adv(uuid, 0, prov_addr, 0);
}

static void prov_complete(uint16_t net_idx, uint16_t addr)
{
k_sem_give(&prov_sem);
if (!atomic_test_bit(flags, IS_PROVISIONER)) {
k_sem_give(&prov_sem);
}
}

static void prov_node_added(uint16_t net_idx, uint8_t uuid[16], uint16_t addr,
uint8_t num_elem)
{
LOG_INF("Device 0x%04x provisioned", prov_addr);
prov_addr++;
k_sem_give(&prov_sem);
}

extern const struct bt_mesh_comp comp;
extern const uint8_t test_net_key[16];
static const uint8_t dev_key[16] = { 0x01, 0x02, 0x03, 0x04, 0x05 };
static const uint8_t dev_uuid[16] = { 0x6c, 0x69, 0x6e, 0x67, 0x61, 0x6f };
static struct bt_mesh_prov prov = {
.uuid = dev_uuid,
.unprovisioned_beacon = unprovisioned_beacon,
Expand Down Expand Up @@ -95,7 +119,8 @@ static void test_device_pb_adv_no_oob(void)

LOG_INF("Mesh initialized\n");

ASSERT_OK(k_sem_take(&prov_sem, K_SECONDS(20)),
/* Keep a long timeout so the prov multi case has time to finish: */
ASSERT_OK(k_sem_take(&prov_sem, K_SECONDS(40)),
"Device provision fail");

PASS();
Expand All @@ -117,14 +142,36 @@ static void test_provisioner_pb_adv_no_oob(void)
err = bt_mesh_provision(test_net_key, 0, 0, 0, 0x0001, dev_key);
ASSERT_OK(err, "Provisioning failed (err %d)", err);

k_sem_take(&prov_sem, K_NO_WAIT);

ASSERT_OK(k_sem_take(&prov_sem, K_SECONDS(20)),
ASSERT_OK(k_sem_take(&prov_sem, K_SECONDS(5)),
"Provisioner provision fail");

PASS();
}

/** @brief Verify that the provisioner can provision multiple devices in a row
*/
static void test_provisioner_pb_adv_multi(void)
{
int err;

k_sem_init(&prov_sem, 0, 1);

bt_mesh_device_setup();

err = bt_mesh_cdb_create(test_net_key);
ASSERT_OK(err, "Failed to create CDB (err %d)\n", err);

err = bt_mesh_provision(test_net_key, 0, 0, 0, 0x0001, dev_key);
ASSERT_OK(err, "Provisioning failed (err %d)", err);

for (int i = 0; i < PROV_MULTI_COUNT; i++) {
ASSERT_OK(k_sem_take(&prov_sem, K_SECONDS(20)),
"Provisioner provision #%d fail", i);
}

PASS();
}

#define TEST_CASE(role, name, description) \
{ \
.test_id = "prov_" #role "_" #name, .test_descr = description, \
Expand All @@ -139,6 +186,8 @@ static const struct bst_test_instance test_connect[] = {

TEST_CASE(provisioner, pb_adv_no_oob,
"Provisioner: pb-adv provisioning use no-oob method"),
TEST_CASE(provisioner, pb_adv_multi,
"Provisioner: pb-adv provisioning multiple devices"),

BSTEST_END_MARKER
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/usr/bin/env bash
# Copyright 2021 Nordic Semiconductor
# SPDX-License-Identifier: Apache-2.0

source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh

# Provision 3 devices in succession:
# Note that the number of devices must match the
# PROV_MULTI_COUNT define in test_provision.c
RunTest mesh_provision_pb_adv_multi \
prov_provisioner_pb_adv_multi \
prov_device_pb_adv_no_oob \
prov_device_pb_adv_no_oob \
prov_device_pb_adv_no_oob \

0 comments on commit e6000e6

Please sign in to comment.