Bluetooth: mesh: added OPcode aggregator Bsim test
The test checks the Opcode aggregator (SIG) model basic behaviour. Signed-off-by: Stine Akredalen <stine.akredalen@nordicsemi.no>
This commit is contained in:
parent
0bd0071e4a
commit
87a3e31412
5 changed files with 275 additions and 0 deletions
|
@ -68,6 +68,7 @@ else()
|
|||
if(CONFIG_BT_MESH_V1d1)
|
||||
target_sources(app PRIVATE
|
||||
src/test_blob.c
|
||||
src/test_op_agg.c
|
||||
src/test_sar.c
|
||||
src/test_lcd.c
|
||||
)
|
||||
|
|
|
@ -53,6 +53,8 @@ CONFIG_BT_MESH_BLOB_CLI=y
|
|||
CONFIG_BT_MESH_BLOB_BLOCK_SIZE_MIN=256
|
||||
CONFIG_BT_MESH_RPR_CLI=y
|
||||
CONFIG_BT_MESH_RPR_SRV=y
|
||||
CONFIG_BT_MESH_OP_AGG_CLI=y
|
||||
CONFIG_BT_MESH_OP_AGG_SRV=y
|
||||
CONFIG_BT_MESH_LARGE_COMP_DATA_CLI=y
|
||||
CONFIG_BT_MESH_LARGE_COMP_DATA_SRV=y
|
||||
CONFIG_BT_MESH_DFU_SRV=y
|
||||
|
|
|
@ -31,6 +31,7 @@ extern struct bst_test_list *test_ivi_install(struct bst_test_list *test);
|
|||
extern struct bst_test_list *test_adv_install(struct bst_test_list *test);
|
||||
#if defined(CONFIG_BT_MESH_V1d1)
|
||||
extern struct bst_test_list *test_blob_install(struct bst_test_list *test);
|
||||
extern struct bst_test_list *test_op_agg_install(struct bst_test_list *test);
|
||||
extern struct bst_test_list *test_sar_install(struct bst_test_list *test);
|
||||
extern struct bst_test_list *test_lcd_install(struct bst_test_list *test);
|
||||
#endif /* defined(CONFIG_BT_MESH_V1d1) */
|
||||
|
@ -61,6 +62,7 @@ bst_test_install_t test_installers[] = {
|
|||
test_adv_install,
|
||||
#if defined(CONFIG_BT_MESH_V1d1)
|
||||
test_blob_install,
|
||||
test_op_agg_install,
|
||||
test_sar_install,
|
||||
test_lcd_install,
|
||||
#endif /* defined(CONFIG_BT_MESH_V1d1) */
|
||||
|
|
243
tests/bluetooth/bsim/mesh/src/test_op_agg.c
Normal file
243
tests/bluetooth/bsim/mesh/src/test_op_agg.c
Normal file
|
@ -0,0 +1,243 @@
|
|||
/*
|
||||
* Copyright (c) 2022 Nordic Semiconductor
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Opcode aggregator test
|
||||
*/
|
||||
|
||||
#include "mesh_test.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <zephyr/logging/log.h>
|
||||
|
||||
LOG_MODULE_REGISTER(test_op_agg, LOG_LEVEL_INF);
|
||||
|
||||
#define CLI_ADDR 0x7728
|
||||
#define SRV_ADDR 0x18f8
|
||||
#define WAIT_TIME 15 /* seconds */
|
||||
#define SEM_TIMEOUT K_SECONDS(10)
|
||||
|
||||
#define BT_MESH_DUMMY_VND_MOD_GET_OP BT_MESH_MODEL_OP_3(0xDC, TEST_VND_COMPANY_ID)
|
||||
#define BT_MESH_DUMMY_VND_MOD_STATUS_OP BT_MESH_MODEL_OP_3(0xCD, TEST_VND_COMPANY_ID)
|
||||
|
||||
#define BT_MESH_DUMMY_VND_MOD_MSG_MINLEN 7
|
||||
#define BT_MESH_DUMMY_VND_MOD_MSG_MAXLEN 8
|
||||
|
||||
/* The 34 messages make up the aggregated message sequence, expecting a 380 byte status response. */
|
||||
#define TEST_SEND_ITR 34
|
||||
|
||||
/* Spec: 4.3.9.4: Table 4.273 defines the structure of the OPCODES_AGGREGATOR_STATUS message. */
|
||||
#define OPCODES_AGG_STATUS_MSG_BASE_STRUCTURE_LEN 5
|
||||
/* SPEC: 4.3.9.1: Length_format + Length_Short.*/
|
||||
#define OPCODES_AGG_ITEM_SHORT_FORMAT_LEN 1
|
||||
/* SPEC: 4.3.9.1: The structure of an Aggregator Item field is defined in Table 4.270 */
|
||||
#define OPCODES_STATUS_ITEM_LEN(param_len) \
|
||||
(OPCODES_AGG_ITEM_SHORT_FORMAT_LEN + \
|
||||
BT_MESH_MODEL_OP_LEN(BT_MESH_DUMMY_VND_MOD_STATUS_OP) + param_len)
|
||||
/* Spec: 4.3.9.3 OPCODES_AGGREGATOR_STATUS. The test initiates 33+1 get/status message iterations.*/
|
||||
#define OP_AGG_STATUS_ACCESS_PAYLOAD \
|
||||
(OPCODES_AGG_STATUS_MSG_BASE_STRUCTURE_LEN + \
|
||||
(OPCODES_STATUS_ITEM_LEN(BT_MESH_DUMMY_VND_MOD_MSG_MINLEN) * (TEST_SEND_ITR - 1)) + \
|
||||
OPCODES_STATUS_ITEM_LEN(BT_MESH_DUMMY_VND_MOD_MSG_MAXLEN))
|
||||
|
||||
/* Ensure that a 380-byte opcode aggregator get/status access payload is being sent. */
|
||||
BUILD_ASSERT(OP_AGG_STATUS_ACCESS_PAYLOAD == (BT_MESH_TX_SDU_MAX - BT_MESH_MIC_SHORT));
|
||||
|
||||
static int status_rcvd_count;
|
||||
static int get_rcvd_count;
|
||||
static struct k_sem cli_suspend_sem;
|
||||
static struct k_sem srv_suspend_sem;
|
||||
static const uint8_t dev_key[16] = {0xaa};
|
||||
static uint8_t cli_sent_array[TEST_SEND_ITR], cli_rcvd_array[TEST_SEND_ITR];
|
||||
|
||||
static struct bt_mesh_msg_ctx test_ctx = {
|
||||
.net_idx = 0,
|
||||
.app_idx = 0,
|
||||
.addr = SRV_ADDR,
|
||||
};
|
||||
|
||||
static struct bt_mesh_prov prov;
|
||||
static struct bt_mesh_cfg_cli cfg_cli;
|
||||
|
||||
static int get_handler(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx,
|
||||
struct net_buf_simple *buf)
|
||||
{
|
||||
uint8_t seq = net_buf_simple_pull_u8(buf);
|
||||
|
||||
get_rcvd_count++;
|
||||
|
||||
BT_MESH_MODEL_BUF_DEFINE(msg, BT_MESH_DUMMY_VND_MOD_STATUS_OP,
|
||||
BT_MESH_DUMMY_VND_MOD_MSG_MAXLEN);
|
||||
bt_mesh_model_msg_init(&msg, BT_MESH_DUMMY_VND_MOD_STATUS_OP);
|
||||
|
||||
net_buf_simple_add_u8(&msg, seq);
|
||||
net_buf_simple_add(&msg, BT_MESH_DUMMY_VND_MOD_MSG_MINLEN - 1);
|
||||
|
||||
/* Last message: One additional byte is added to fill the available access payload.*/
|
||||
if (get_rcvd_count >= TEST_SEND_ITR) {
|
||||
net_buf_simple_add(&msg, 1);
|
||||
k_sem_give(&srv_suspend_sem);
|
||||
}
|
||||
|
||||
return bt_mesh_model_send(model, ctx, &msg, NULL, NULL);
|
||||
}
|
||||
|
||||
static int status_handler(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx,
|
||||
struct net_buf_simple *buf)
|
||||
{
|
||||
uint8_t seq = net_buf_simple_pull_u8(buf);
|
||||
|
||||
status_rcvd_count++;
|
||||
cli_rcvd_array[status_rcvd_count - 1] = seq;
|
||||
|
||||
if (status_rcvd_count >= TEST_SEND_ITR) {
|
||||
k_sem_give(&cli_suspend_sem);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dummy_vnd_mod_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, uint8_t seq)
|
||||
{
|
||||
BT_MESH_MODEL_BUF_DEFINE(msg, BT_MESH_DUMMY_VND_MOD_GET_OP,
|
||||
BT_MESH_DUMMY_VND_MOD_MSG_MAXLEN);
|
||||
|
||||
bt_mesh_model_msg_init(&msg, BT_MESH_DUMMY_VND_MOD_GET_OP);
|
||||
|
||||
net_buf_simple_add_u8(&msg, seq);
|
||||
net_buf_simple_add(&msg, BT_MESH_DUMMY_VND_MOD_MSG_MINLEN - 1);
|
||||
|
||||
/* Last message: One additional byte is added to fill the available access payload.*/
|
||||
if (seq >= TEST_SEND_ITR - 1) {
|
||||
net_buf_simple_add(&msg, 1);
|
||||
}
|
||||
|
||||
return bt_mesh_model_send(model, ctx, &msg, NULL, NULL);
|
||||
}
|
||||
|
||||
const struct bt_mesh_model_op _dummy_vnd_mod_op[] = {
|
||||
{BT_MESH_DUMMY_VND_MOD_GET_OP, BT_MESH_DUMMY_VND_MOD_MSG_MINLEN, get_handler},
|
||||
{BT_MESH_DUMMY_VND_MOD_STATUS_OP, BT_MESH_DUMMY_VND_MOD_MSG_MINLEN, status_handler},
|
||||
BT_MESH_MODEL_OP_END,
|
||||
};
|
||||
|
||||
static struct bt_mesh_model dummy_vnd_model = {
|
||||
.op = _dummy_vnd_mod_op,
|
||||
.vnd.id = TEST_VND_MOD_ID,
|
||||
.vnd.company = TEST_VND_COMPANY_ID,
|
||||
};
|
||||
|
||||
static struct bt_mesh_elem elements[] = {BT_MESH_ELEM(
|
||||
0,
|
||||
MODEL_LIST(BT_MESH_MODEL_CFG_SRV, BT_MESH_MODEL_CFG_CLI(&cfg_cli), BT_MESH_MODEL_OP_AGG_SRV,
|
||||
BT_MESH_MODEL_OP_AGG_CLI),
|
||||
MODEL_LIST(BT_MESH_MODEL_VND_CB(TEST_VND_COMPANY_ID, TEST_VND_MOD_ID, _dummy_vnd_mod_op,
|
||||
NULL, &dummy_vnd_model, NULL)))};
|
||||
|
||||
static const struct bt_mesh_comp comp = {
|
||||
.cid = TEST_VND_COMPANY_ID,
|
||||
.elem = elements,
|
||||
.elem_count = ARRAY_SIZE(elements),
|
||||
};
|
||||
|
||||
static void op_agg_test_prov_and_conf(uint16_t addr)
|
||||
{
|
||||
uint8_t status;
|
||||
int err;
|
||||
|
||||
ASSERT_OK(bt_mesh_provision(test_net_key, 0, 0, 0, addr, dev_key));
|
||||
|
||||
err = bt_mesh_cfg_cli_app_key_add(0, addr, 0, 0, test_app_key, &status);
|
||||
if (err || status) {
|
||||
FAIL("AppKey add failed (err %d, status %u)", err, status);
|
||||
}
|
||||
|
||||
err = bt_mesh_cfg_cli_mod_app_bind(0, addr, addr, 0, BT_MESH_MODEL_ID_OP_AGG_CLI,
|
||||
&status);
|
||||
if (err || status) {
|
||||
FAIL("Failed to bind OP_AGG_CLI to application (err %d, status %u)", err, status);
|
||||
}
|
||||
err = bt_mesh_cfg_cli_mod_app_bind(0, addr, addr, 0, BT_MESH_MODEL_ID_OP_AGG_SRV,
|
||||
&status);
|
||||
if (err || status) {
|
||||
FAIL("Failed to bind OP_AGG_SRV to application (err %d, status %u)", err, status);
|
||||
}
|
||||
err = bt_mesh_cfg_cli_mod_app_bind_vnd(0, addr, addr, 0, TEST_VND_MOD_ID,
|
||||
TEST_VND_COMPANY_ID, &status);
|
||||
if (err || status) {
|
||||
FAIL("Failed to bind OP_AGG_TEST_MOD to application (err %d, status %u)", err,
|
||||
status);
|
||||
}
|
||||
}
|
||||
|
||||
static void test_cli_max_len_sequence_msg_send(void)
|
||||
{
|
||||
uint8_t seq;
|
||||
|
||||
bt_mesh_test_cfg_set(NULL, WAIT_TIME);
|
||||
bt_mesh_device_setup(&prov, &comp);
|
||||
op_agg_test_prov_and_conf(CLI_ADDR);
|
||||
|
||||
ASSERT_OK(k_sem_init(&cli_suspend_sem, 0, 1));
|
||||
ASSERT_OK(bt_mesh_op_agg_cli_seq_start(0, 0, SRV_ADDR, SRV_ADDR));
|
||||
|
||||
for (int i = 0; i < TEST_SEND_ITR; i++) {
|
||||
seq = cli_sent_array[i] = i;
|
||||
ASSERT_OK(dummy_vnd_mod_get(&dummy_vnd_model, &test_ctx, seq));
|
||||
}
|
||||
|
||||
ASSERT_OK(bt_mesh_op_agg_cli_seq_send());
|
||||
|
||||
/* Wait for all expected STATUS messages to be received */
|
||||
if (k_sem_take(&cli_suspend_sem, SEM_TIMEOUT)) {
|
||||
FAIL("Client suspension timed out. Status-messages received: %d",
|
||||
status_rcvd_count);
|
||||
}
|
||||
|
||||
if (memcmp(cli_sent_array, cli_rcvd_array, ARRAY_SIZE(cli_rcvd_array))) {
|
||||
FAIL("Message arrays (sent / rcvd) are not equal.");
|
||||
}
|
||||
|
||||
PASS();
|
||||
}
|
||||
|
||||
static void test_srv_max_len_status_msg_send(void)
|
||||
{
|
||||
bt_mesh_test_cfg_set(NULL, WAIT_TIME);
|
||||
bt_mesh_device_setup(&prov, &comp);
|
||||
op_agg_test_prov_and_conf(SRV_ADDR);
|
||||
|
||||
ASSERT_OK(k_sem_init(&srv_suspend_sem, 0, 1));
|
||||
|
||||
/* Wait for all expected GET messages to be received */
|
||||
if (k_sem_take(&srv_suspend_sem, SEM_TIMEOUT)) {
|
||||
FAIL("Server suspension timed out. Get-messages received: %d", get_rcvd_count);
|
||||
}
|
||||
|
||||
PASS();
|
||||
}
|
||||
|
||||
#define TEST_CASE(role, name, description) \
|
||||
{ \
|
||||
.test_id = "op_agg_" #role "_" #name, \
|
||||
.test_descr = description, \
|
||||
.test_tick_f = bt_mesh_test_timeout, \
|
||||
.test_main_f = test_##role##_##name, \
|
||||
}
|
||||
|
||||
static const struct bst_test_instance test_op_agg[] = {
|
||||
TEST_CASE(cli, max_len_sequence_msg_send,
|
||||
"OpAggCli composes a sequence request list, expecting a 380 Byte status message "
|
||||
"in return."),
|
||||
TEST_CASE(srv, max_len_status_msg_send,
|
||||
"OpAggSrv will respond with a 380 Byte status message. "),
|
||||
|
||||
BSTEST_END_MARKER};
|
||||
|
||||
struct bst_test_list *test_op_agg_install(struct bst_test_list *tests)
|
||||
{
|
||||
tests = bst_add_tests(tests, test_op_agg);
|
||||
return tests;
|
||||
}
|
27
tests/bluetooth/bsim/mesh/tests_scripts/op_agg/full_status_msg_list.sh
Executable file
27
tests/bluetooth/bsim/mesh/tests_scripts/op_agg/full_status_msg_list.sh
Executable file
|
@ -0,0 +1,27 @@
|
|||
#!/usr/bin/env bash
|
||||
# Copyright 2022 Nordic Semiconductor
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh
|
||||
|
||||
# Test that the OPcode aggregator (op agg) SIG model is able to send and receive a 380-byte
|
||||
# access payload message and that the status item messages are received in the correct order.
|
||||
# Spec 3.7.2: "With a 32-bit TransMIC field, the maximum size of the Access message is 380 octets."
|
||||
# Spec 4.4.19.2: "When an Access message or an empty item is added to the message results list,
|
||||
# it shall be located at the same index as the corresponding Access message from
|
||||
# the message request list."
|
||||
|
||||
# Test procedure:
|
||||
# 1. Initialize and configure op agg client and server instances.
|
||||
# 2. The client configures op agg context.
|
||||
# 3. The client sends X vendor model messages, making up an op agg sequence message of 380 bytes.
|
||||
# 4. The client sends the sequence message with the previously configured context,
|
||||
# expecting an op agg status message of 380 bytes in return.
|
||||
# 5. The server keeps track of the number of received messages and pass when X messages have been
|
||||
# received.
|
||||
# 6. The client keeps track of the number of received status messages. When X messages have been
|
||||
# received, the client pass if the sequence of received status messages corresponds to the order
|
||||
# in which the messages were sent, or the test fails.
|
||||
conf=prj_mesh1d1_conf
|
||||
RunTest mesh_op_agg_test_max_access_payload \
|
||||
op_agg_cli_max_len_sequence_msg_send op_agg_srv_max_len_status_msg_send
|
Loading…
Add table
Add a link
Reference in a new issue