From acccd46306b2de026add59ea3d75c4a1b81cfc44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5vard=20Reierstad?= Date: Tue, 25 Mar 2025 12:17:48 +0100 Subject: [PATCH] Bluetooth: Mesh: Test pb cancelling in bsim MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds a provision test to check that provisioning bearers are cancelled when a provisioning link is opened. Modifies the functionality for receiving unprovisioned beacons to fail the test if a unprovisioned beacon is received from the current provisionee after a threshold. Signed-off-by: HÃ¥vard Reierstad --- .../bsim/bluetooth/mesh/src/test_provision.c | 115 +++++++++++++++++- .../mesh/tests_scripts/provision/pb_cancel.sh | 27 ++++ 2 files changed, 138 insertions(+), 4 deletions(-) create mode 100755 tests/bsim/bluetooth/mesh/tests_scripts/provision/pb_cancel.sh diff --git a/tests/bsim/bluetooth/mesh/src/test_provision.c b/tests/bsim/bluetooth/mesh/src/test_provision.c index d47e274a6a6..67cccfd9316 100644 --- a/tests/bsim/bluetooth/mesh/src/test_provision.c +++ b/tests/bsim/bluetooth/mesh/src/test_provision.c @@ -42,6 +42,8 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #define WAIT_TIME 120 /*seconds*/ #define IS_RPR_PRESENT (CONFIG_BT_MESH_RPR_SRV && CONFIG_BT_MESH_RPR_CLI) #define IMPOSTER_MODEL_ID 0xe000 +/* Rough estimate of the time it should take the provisionee to stop sending unprov beacons. */ +#define PROV_DELTA_THRESH_MS 100 enum test_flags { IS_PROVISIONER, @@ -101,6 +103,7 @@ static uint32_t link_close_timestamp; /* Set prov_bearer to non-zero invalid value. */ static bt_mesh_prov_bearer_t prov_bearer = 0xF8; +static bt_mesh_prov_bearer_t prov_to_use; static void test_args_parse(int argc, char *argv[]) { @@ -108,10 +111,18 @@ static void test_args_parse(int argc, char *argv[]) { .dest = &prov_bearer, .type = 'i', - .name = "{invalid, PB-ADV, PB-GATT}", + .name = "{invalid, PB-ADV, PB-GATT, (PB-ADV | PB-GATT)}", .option = "prov-bearer", .descript = "Provisioning bearer that is to be used." }, + { + .dest = &prov_to_use, + .type = 'i', + .name = "{PB-ADV, PB-GATT}", + .option = "prov-to-use", + .descript = "Provisioning bearer that is to be used in the case that " + "multiple provisioning bearers are enabled in prov_bearer." + }, }; bs_args_parse_all_cmd_line(argc, argv, args_struct); @@ -279,6 +290,42 @@ static void test_terminate(void) } } +static uint64_t prov_started_time_ms; +static uint8_t prov_uuid[16]; + +static void provision(uint8_t uuid[16], bt_mesh_prov_bearer_t bearer) +{ + int err; + + switch (bearer) { + case BT_MESH_PROV_ADV: + err = bt_mesh_provision_adv(uuid, 0, prov_addr, 0); + break; + case BT_MESH_PROV_GATT: + err = bt_mesh_provision_gatt(uuid, 0, prov_addr, 0); + break; + default: + err = -ENOTSUP; + } + + if (!err) { + LOG_INF("Provisioning over %s started.", + bearer == BT_MESH_PROV_ADV ? "PB-ADV" : "PB-GATT"); + prov_started_time_ms = k_uptime_get(); + memcpy(prov_uuid, uuid, 16); + } +} + +static void provisionee_beacon_check(uint8_t uuid[16], bt_mesh_prov_bearer_t bearer) +{ + if (memcmp(uuid, prov_uuid, 16) == 0) { + ASSERT_FALSE_MSG((prov_started_time_ms && + (k_uptime_delta(&prov_started_time_ms) > PROV_DELTA_THRESH_MS)), + "Received %s beacon from provisionee after provisioning started.", + bearer == BT_MESH_PROV_ADV ? "PB-ADV" : "PB-GATT"); + } +} + static void unprovisioned_beacon(uint8_t uuid[16], bt_mesh_prov_oob_info_t oob_info, uint32_t *uri_hash) @@ -290,7 +337,12 @@ static void unprovisioned_beacon(uint8_t uuid[16], if (uuid_to_provision && memcmp(uuid, uuid_to_provision, 16)) { return; } - bt_mesh_provision_adv(uuid, 0, prov_addr, 0); + + provisionee_beacon_check(uuid, BT_MESH_PROV_ADV); + + if (!prov_to_use || prov_to_use == BT_MESH_PROV_ADV) { + provision(uuid, BT_MESH_PROV_ADV); + } } static void unprovisioned_beacon_gatt(uint8_t uuid[16], bt_mesh_prov_oob_info_t oob_info) @@ -303,7 +355,11 @@ static void unprovisioned_beacon_gatt(uint8_t uuid[16], bt_mesh_prov_oob_info_t return; } - bt_mesh_provision_gatt(uuid, 0, prov_addr, 0); + provisionee_beacon_check(uuid, BT_MESH_PROV_GATT); + + if (!prov_to_use || prov_to_use == BT_MESH_PROV_GATT) { + provision(uuid, BT_MESH_PROV_GATT); + } } static void prov_complete(uint16_t net_idx, uint16_t addr) @@ -328,6 +384,8 @@ static void prov_node_added(uint16_t net_idx, uint8_t uuid[16], uint16_t addr, { LOG_INF("Device 0x%04x provisioned", prov_addr); current_dev_addr = prov_addr++; + prov_started_time_ms = 0; + memset(prov_uuid, 0, 16); k_sem_give(&prov_sem); } @@ -344,6 +402,7 @@ static void prov_reset(void) static bt_mesh_input_action_t gact; static uint8_t gsize; +static bool oob_wait_unprov_int; static int input(bt_mesh_input_action_t act, uint8_t size) { /* The test system requests the input OOB data earlier than @@ -354,7 +413,9 @@ static int input(bt_mesh_input_action_t act, uint8_t size) gact = act; gsize = size; - k_work_reschedule(&oob_timer, K_SECONDS(1)); + k_work_reschedule(&oob_timer, oob_wait_unprov_int + ? K_SECONDS(CONFIG_BT_MESH_UNPROV_BEACON_INT + 1) + : K_SECONDS(1)); return 0; } @@ -745,6 +806,49 @@ static void test_provisioner_oob_auth_no_oob_public_key(void) PASS(); } +static void test_provisioner_pb_cancel(void) +{ + k_sem_init(&prov_sem, 0, 1); + + bt_mesh_device_setup(&prov, &comp); + + ASSERT_OK(bt_mesh_cdb_create(test_net_key)); + + ASSERT_OK(bt_mesh_provision(test_net_key, 0, 0, 0, 0x0001, dev_key)); + + prov.static_val = 0; + prov.static_val_len = 0; + prov.output_size = 0; + prov.output_actions = 0; + prov.input_size = 8; + prov.input_actions = BT_MESH_ENTER_NUMBER; + + ASSERT_OK(k_sem_take(&prov_sem, K_SECONDS(20))); + + PASS(); +} + +static void test_device_pb_cancel(void) +{ + oob_wait_unprov_int = true; + k_sem_init(&prov_sem, 0, 1); + + bt_mesh_device_setup(&prov, &comp); + + prov.static_val = 0; + prov.static_val_len = 0; + prov.output_size = 0; + prov.output_actions = 0; + prov.input_size = 8; + prov.input_actions = BT_MESH_ENTER_NUMBER; + + ASSERT_OK(bt_mesh_prov_enable(prov_bearer)); + + ASSERT_OK(k_sem_take(&prov_sem, K_SECONDS(20))); + + PASS(); +} + /** @brief Verify that the provisioner can provision multiple devices in a row */ static void test_provisioner_multi(void) @@ -1809,6 +1913,7 @@ static const struct bst_test_instance test_connect[] = { TEST_CASE_WBACKCHANNEL(device, oob_public_key, "Device: provisioning use oob public key"), TEST_CASE(device, reprovision, "Device: provisioning, reprovision"), + TEST_CASE_WBACKCHANNEL(device, pb_cancel, "Device: provisioning, cancel prov bearers."), #if IS_RPR_PRESENT TEST_CASE(device, pb_remote_server_unproved, "Device: used for remote provisioning, starts unprovisioned"), @@ -1839,6 +1944,8 @@ static const struct bst_test_instance test_connect[] = { TEST_CASE( provisioner, reprovision, "Provisioner: provisioning, resetting and reprovisioning multiple times."), + TEST_CASE_WBACKCHANNEL( + provisioner, pb_cancel, "Provisioner: provisioning, cancel prov bearers."), #if IS_RPR_PRESENT TEST_CASE(provisioner, pb_remote_client_reprovision, "Provisioner: pb-remote provisioning, resetting and reprov-ing multiple times."), diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/provision/pb_cancel.sh b/tests/bsim/bluetooth/mesh/tests_scripts/provision/pb_cancel.sh new file mode 100755 index 00000000000..df2723a2270 --- /dev/null +++ b/tests/bsim/bluetooth/mesh/tests_scripts/provision/pb_cancel.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash +# Copyright 2025 Nordic Semiconductor +# SPDX-License-Identifier: Apache-2.0 + +source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh + +# Test that PB-ADV and PB-GATT unprovisioned beacons are cancelled when a provisioning link is +# opened. +# Test procedure: +# 1. The provisioner self-provisions and starts scanning for unprovisioned devices. +# 2. The provisionee enables both the PB-ADV and PB-GATT bearers. +# 3. The provisioner finds the unprovisioned device and provisions it with OOB authentication. +# The OOB authentication is delayed by CONFIG_BT_MESH_UNPROV_BEACON_INT + 1 seconds to ensure +# that the provisioner has time observe that PB-ADV and PB-GATT beacons are cancelled. +# 4. The provisioning procedure completes. + +overlay=overlay_gatt_conf_overlay_psa_conf +RunTest mesh_prov_pb_cancel_adv \ + prov_provisioner_pb_cancel \ + prov_device_pb_cancel \ + -- -argstest prov-bearer=3 prov-to-use=1 + +overlay=overlay_gatt_conf_overlay_psa_conf +RunTest mesh_prov_pb_cancel_gatt \ + prov_provisioner_pb_cancel \ + prov_device_pb_cancel \ + -- -argstest prov-bearer=3 prov-to-use=2