blob: e5ec29914e5c7ece9a7a3f54d701a1e535319be5 [file] [log] [blame]
/*
* Copyright (c) 2021 Nordic Semiconductor
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <kernel.h>
#include "mesh_test.h"
#include "mesh/net.h"
#include "mesh/beacon.h"
#include "mesh/mesh.h"
#include "mesh/foundation.h"
#define LOG_MODULE_NAME test_beacon
#include <logging/log.h>
LOG_MODULE_REGISTER(LOG_MODULE_NAME, LOG_LEVEL_INF);
#define GROUP_ADDR 0xc000
#define WAIT_TIME 60 /*seconds*/
#define BEACON_INTERVAL K_SECONDS(10)
extern enum bst_result_t bst_result;
static const struct bt_mesh_test_cfg tx_cfg = {
.addr = 0x0001,
.dev_key = { 0x01 },
};
static const struct bt_mesh_test_cfg rx_cfg = {
.addr = 0x0002,
.dev_key = { 0x02 },
};
static void test_tx_init(void)
{
bt_mesh_test_cfg_set(&tx_cfg, WAIT_TIME);
}
static void test_rx_init(void)
{
bt_mesh_test_cfg_set(&rx_cfg, WAIT_TIME);
}
static void ivu_log(void)
{
LOG_DBG("ivi: %i", bt_mesh.iv_index);
LOG_DBG("flags:");
if (atomic_test_bit(bt_mesh.flags, BT_MESH_IVU_INITIATOR)) {
LOG_DBG("IVU initiator");
}
if (atomic_test_bit(bt_mesh.flags, BT_MESH_IVU_IN_PROGRESS)) {
LOG_DBG("IVU in progress");
}
if (atomic_test_bit(bt_mesh.flags, BT_MESH_IVU_PENDING)) {
LOG_DBG("IVU pending");
}
if (atomic_test_bit(bt_mesh.flags, BT_MESH_IVU_TEST)) {
LOG_DBG("IVU in test mode");
}
}
static void test_tx_on_iv_update(void)
{
bt_mesh_test_setup();
ASSERT_TRUE(!atomic_test_bit(bt_mesh.flags, BT_MESH_IVU_INITIATOR));
ASSERT_TRUE(!atomic_test_bit(bt_mesh.flags, BT_MESH_IVU_IN_PROGRESS));
ASSERT_TRUE(!atomic_test_bit(bt_mesh.flags, BT_MESH_IVU_PENDING));
ASSERT_TRUE(!atomic_test_bit(bt_mesh.flags, BT_MESH_IVU_TEST));
ASSERT_TRUE(bt_mesh.iv_index == 0);
/* shift beaconing time line to avoid boundary cases. */
k_sleep(K_SECONDS(1));
bt_mesh_iv_update_test(true);
ASSERT_TRUE(atomic_test_bit(bt_mesh.flags, BT_MESH_IVU_TEST));
ASSERT_TRUE(bt_mesh_iv_update());
ASSERT_TRUE(atomic_test_bit(bt_mesh.flags, BT_MESH_IVU_IN_PROGRESS));
ASSERT_TRUE(bt_mesh.iv_index == 1);
k_sleep(BEACON_INTERVAL);
ASSERT_TRUE(!bt_mesh_iv_update());
ASSERT_TRUE(!atomic_test_bit(bt_mesh.flags, BT_MESH_IVU_IN_PROGRESS));
ASSERT_TRUE(bt_mesh.iv_index == 1);
k_sleep(BEACON_INTERVAL);
ASSERT_TRUE(bt_mesh_iv_update());
ASSERT_TRUE(atomic_test_bit(bt_mesh.flags, BT_MESH_IVU_IN_PROGRESS));
ASSERT_TRUE(bt_mesh.iv_index == 2);
k_sleep(BEACON_INTERVAL);
PASS();
}
static void test_rx_on_iv_update(void)
{
bt_mesh_test_setup();
/* disable beaconing from Rx device to prevent
* the time line adaptation due to observation algorithm.
*/
bt_mesh_beacon_disable();
ASSERT_TRUE(!atomic_test_bit(bt_mesh.flags, BT_MESH_IVU_INITIATOR));
ASSERT_TRUE(!atomic_test_bit(bt_mesh.flags, BT_MESH_IVU_IN_PROGRESS));
ASSERT_TRUE(!atomic_test_bit(bt_mesh.flags, BT_MESH_IVU_PENDING));
ASSERT_TRUE(!atomic_test_bit(bt_mesh.flags, BT_MESH_IVU_TEST));
ASSERT_TRUE(bt_mesh.iv_index == 0);
/* shift beaconing time line to avoid boundary cases. */
k_sleep(K_SECONDS(1));
bt_mesh_iv_update_test(true);
ASSERT_TRUE(atomic_test_bit(bt_mesh.flags, BT_MESH_IVU_TEST));
ivu_log();
k_sleep(BEACON_INTERVAL);
ASSERT_TRUE(atomic_test_bit(bt_mesh.flags, BT_MESH_IVU_IN_PROGRESS));
ASSERT_TRUE(bt_mesh.iv_index == 1);
ivu_log();
k_sleep(BEACON_INTERVAL);
ASSERT_TRUE(!atomic_test_bit(bt_mesh.flags, BT_MESH_IVU_IN_PROGRESS));
ASSERT_TRUE(bt_mesh.iv_index == 1);
ivu_log();
k_sleep(BEACON_INTERVAL);
ASSERT_TRUE(atomic_test_bit(bt_mesh.flags, BT_MESH_IVU_IN_PROGRESS));
ASSERT_TRUE(bt_mesh.iv_index == 2);
ivu_log();
PASS();
}
static void test_tx_on_key_refresh(void)
{
const uint8_t new_key[16] = {0x01};
uint8_t phase;
uint8_t status;
bt_mesh_test_setup();
status = bt_mesh_subnet_kr_phase_get(BT_MESH_KEY_PRIMARY, &phase);
ASSERT_TRUE(status == STATUS_SUCCESS);
ASSERT_TRUE(phase == BT_MESH_KR_NORMAL);
/* shift beaconing time line to avoid boundary cases. */
k_sleep(K_SECONDS(1));
status = bt_mesh_subnet_update(BT_MESH_KEY_PRIMARY, new_key);
ASSERT_TRUE(status == STATUS_SUCCESS);
status = bt_mesh_subnet_kr_phase_get(BT_MESH_KEY_PRIMARY, &phase);
ASSERT_TRUE(status == STATUS_SUCCESS);
ASSERT_TRUE(phase == BT_MESH_KR_PHASE_1);
k_sleep(BEACON_INTERVAL);
phase = BT_MESH_KR_PHASE_2;
status = bt_mesh_subnet_kr_phase_set(BT_MESH_KEY_PRIMARY, &phase);
ASSERT_TRUE(status == STATUS_SUCCESS);
status = bt_mesh_subnet_kr_phase_get(BT_MESH_KEY_PRIMARY, &phase);
ASSERT_TRUE(status == STATUS_SUCCESS);
ASSERT_TRUE(phase == BT_MESH_KR_PHASE_2);
k_sleep(BEACON_INTERVAL);
phase = BT_MESH_KR_PHASE_3;
status = bt_mesh_subnet_kr_phase_set(BT_MESH_KEY_PRIMARY, &phase);
ASSERT_TRUE(status == STATUS_SUCCESS);
status = bt_mesh_subnet_kr_phase_get(BT_MESH_KEY_PRIMARY, &phase);
ASSERT_TRUE(status == STATUS_SUCCESS);
ASSERT_TRUE(phase == BT_MESH_KR_NORMAL);
k_sleep(BEACON_INTERVAL);
PASS();
}
static void test_rx_on_key_refresh(void)
{
const uint8_t new_key[16] = {0x01};
uint8_t phase;
uint8_t status;
bt_mesh_test_setup();
/* disable beaconing from Rx device to prevent
* the time line adaptation due to observation algorithm.
*/
bt_mesh_beacon_disable();
status = bt_mesh_subnet_kr_phase_get(BT_MESH_KEY_PRIMARY, &phase);
ASSERT_TRUE(status == STATUS_SUCCESS);
ASSERT_TRUE(phase == BT_MESH_KR_NORMAL);
/* shift beaconing time line to avoid boundary cases. */
k_sleep(K_SECONDS(1));
status = bt_mesh_subnet_update(BT_MESH_KEY_PRIMARY, new_key);
ASSERT_TRUE(status == STATUS_SUCCESS);
status = bt_mesh_subnet_kr_phase_get(BT_MESH_KEY_PRIMARY, &phase);
ASSERT_TRUE(status == STATUS_SUCCESS);
ASSERT_TRUE(phase == BT_MESH_KR_PHASE_1);
k_sleep(BEACON_INTERVAL);
status = bt_mesh_subnet_kr_phase_get(BT_MESH_KEY_PRIMARY, &phase);
ASSERT_TRUE(status == STATUS_SUCCESS);
ASSERT_TRUE(phase == BT_MESH_KR_PHASE_1);
k_sleep(BEACON_INTERVAL);
status = bt_mesh_subnet_kr_phase_get(BT_MESH_KEY_PRIMARY, &phase);
ASSERT_TRUE(status == STATUS_SUCCESS);
ASSERT_TRUE(phase == BT_MESH_KR_PHASE_2);
k_sleep(BEACON_INTERVAL);
status = bt_mesh_subnet_kr_phase_get(BT_MESH_KEY_PRIMARY, &phase);
ASSERT_TRUE(status == STATUS_SUCCESS);
ASSERT_TRUE(phase == BT_MESH_KR_NORMAL);
PASS();
}
#define TEST_CASE(role, name, description) \
{ \
.test_id = "beacon_" #role "_" #name, \
.test_descr = description, \
.test_post_init_f = test_##role##_init, \
.test_tick_f = bt_mesh_test_timeout, \
.test_main_f = test_##role##_##name, \
}
static const struct bst_test_instance test_beacon[] = {
TEST_CASE(tx, on_iv_update, "Beacon: send on IV update"),
TEST_CASE(tx, on_key_refresh, "Beacon: send on key refresh"),
TEST_CASE(rx, on_iv_update, "Beacon: receive with IV update flag"),
TEST_CASE(rx, on_key_refresh, "Beacon: receive with key refresh flag"),
BSTEST_END_MARKER
};
struct bst_test_list *test_beacon_install(struct bst_test_list *tests)
{
tests = bst_add_tests(tests, test_beacon);
return tests;
}