Bluetooth: Mesh: Support for comp data page 129

Adds support for composition data page 129.

Signed-off-by: Anders Storrø <anders.storro@nordicsemi.no>
This commit is contained in:
Anders Storrø 2023-08-24 11:51:33 +02:00 committed by Carles Cufí
commit 8bb7a280eb
5 changed files with 83 additions and 49 deletions

View file

@ -104,6 +104,16 @@ static struct mod_relation mod_rel_list[MOD_REL_LIST_SIZE];
#define RELATION_TYPE_EXT 0xFF
static const struct {
uint8_t *path;
uint8_t page;
} comp_data_pages[] = {
{ "bt/mesh/cmp/0", 0, },
#if IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_1)
{ "bt/mesh/cmp/1", 1, },
#endif
};
void bt_mesh_model_foreach(void (*func)(struct bt_mesh_model *mod,
struct bt_mesh_elem *elem,
bool vnd, bool primary,
@ -2137,25 +2147,41 @@ void bt_mesh_model_pub_store(struct bt_mesh_model *mod)
bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_MOD_PENDING);
}
int bt_mesh_comp_data_get_page(struct net_buf_simple *buf, size_t page, size_t offset)
{
if (page == 0 || page == 128) {
return bt_mesh_comp_data_get_page_0(buf, offset);
} else if (page == 1 || page == 129) {
return bt_mesh_comp_data_get_page_1(buf);
}
return -EINVAL;
}
int bt_mesh_comp_store(void)
{
NET_BUF_SIMPLE_DEFINE(buf, BT_MESH_TX_SDU_MAX);
int err;
err = bt_mesh_comp_data_get_page_0(&buf, 0);
if (err) {
LOG_ERR("Failed to read composition data: %d", err);
return err;
for (int i = 0; i < ARRAY_SIZE(comp_data_pages); i++) {
net_buf_simple_reset(&buf);
err = bt_mesh_comp_data_get_page(&buf, comp_data_pages[i].page, 0);
if (err) {
LOG_ERR("Failed to read CDP%d: %d", comp_data_pages[i].page, err);
return err;
}
err = settings_save_one(comp_data_pages[i].path, buf.data, buf.len);
if (err) {
LOG_ERR("Failed to store CDP%d: %d", comp_data_pages[i].page, err);
return err;
}
LOG_DBG("Stored CDP%d", comp_data_pages[i].page);
}
err = settings_save_one("bt/mesh/cmp", buf.data, buf.len);
if (err) {
LOG_ERR("Failed to store composition data: %d", err);
} else {
LOG_DBG("Stored composition data");
}
return err;
return 0;
}
int bt_mesh_comp_change_prepare(void)
@ -2171,11 +2197,12 @@ static void comp_data_clear(void)
{
int err;
err = settings_delete("bt/mesh/cmp");
if (err) {
LOG_ERR("Failed to clear composition data: %d", err);
} else {
LOG_DBG("Cleared composition data page 128");
for (int i = 0; i < ARRAY_SIZE(comp_data_pages); i++) {
err = settings_delete(comp_data_pages[i].path);
if (err) {
LOG_ERR("Failed to clear CDP%d: %d", comp_data_pages[i].page,
err);
}
}
atomic_clear_bit(bt_mesh.flags, BT_MESH_COMP_DIRTY);
@ -2198,25 +2225,35 @@ static int read_comp_cb(const char *key, size_t len, settings_read_cb read_cb,
return -EALREADY;
}
int bt_mesh_comp_read(struct net_buf_simple *buf)
int bt_mesh_comp_read(struct net_buf_simple *buf, uint8_t page)
{
size_t original_len = buf->len;
int i;
int err;
if (!IS_ENABLED(CONFIG_BT_SETTINGS)) {
return -ENOTSUP;
}
err = settings_load_subtree_direct("bt/mesh/cmp", read_comp_cb, buf);
for (i = 0; i < ARRAY_SIZE(comp_data_pages); i++) {
if (comp_data_pages[i].page == page) {
break;
}
}
if (i == ARRAY_SIZE(comp_data_pages)) {
return -ENOENT;
}
err = settings_load_subtree_direct(comp_data_pages[i].path, read_comp_cb, buf);
if (err) {
LOG_ERR("Failed reading composition data: %d", err);
return err;
}
if (buf->len == original_len) {
return -ENOENT;
}
return 0;
}

View file

@ -64,13 +64,14 @@ int bt_mesh_model_recv(struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf);
int bt_mesh_comp_register(const struct bt_mesh_comp *comp);
int bt_mesh_comp_store(void);
int bt_mesh_comp_read(struct net_buf_simple *buf);
int bt_mesh_comp_read(struct net_buf_simple *buf, uint8_t page);
int bt_mesh_models_metadata_store(void);
int bt_mesh_models_metadata_read(struct net_buf_simple *buf, size_t offset);
void bt_mesh_comp_data_pending_clear(void);
void bt_mesh_comp_data_clear(void);
int bt_mesh_comp_data_get_page(struct net_buf_simple *buf, size_t page, size_t offset);
void bt_mesh_model_pending_store(void);
void bt_mesh_model_bind_store(struct bt_mesh_model *mod);

View file

@ -2321,7 +2321,7 @@ struct bt_mesh_comp_p1_elem *bt_mesh_comp_p1_elem_pull(struct net_buf_simple *bu
struct bt_mesh_comp_p1_elem *elem)
{
if (buf->len < 6) {
LOG_ERR("No more elements to pull or missing data");
LOG_DBG("No more elements to pull or missing data");
return NULL;
}
size_t elem_size = 0;

View file

@ -61,8 +61,12 @@ static int dev_comp_data_get(struct bt_mesh_model *model,
page = net_buf_simple_pull_u8(buf);
if (page >= 128U && (atomic_test_bit(bt_mesh.flags, BT_MESH_COMP_DIRTY) ||
IS_ENABLED(CONFIG_BT_MESH_RPR_SRV))) {
if (page >= 129U && IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_1) &&
(atomic_test_bit(bt_mesh.flags, BT_MESH_COMP_DIRTY) ||
IS_ENABLED(CONFIG_BT_MESH_RPR_SRV))) {
page = 129U;
} else if (page >= 128U && (atomic_test_bit(bt_mesh.flags, BT_MESH_COMP_DIRTY) ||
IS_ENABLED(CONFIG_BT_MESH_RPR_SRV))) {
page = 128U;
} else if (page >= 1U && IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_1)) {
page = 1U;
@ -75,27 +79,18 @@ static int dev_comp_data_get(struct bt_mesh_model *model,
bt_mesh_model_msg_init(&sdu, OP_DEV_COMP_DATA_STATUS);
net_buf_simple_add_u8(&sdu, page);
if (IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_1) && page == 1) {
err = bt_mesh_comp_data_get_page_1(&sdu);
if (err < 0) {
LOG_ERR("Unable to get composition page 1");
return err;
}
} else if (atomic_test_bit(bt_mesh.flags, BT_MESH_COMP_DIRTY) && (page == 0U)) {
sdu.size -= BT_MESH_MIC_SHORT;
err = bt_mesh_comp_read(&sdu);
if (err) {
LOG_ERR("Unable to get stored composition data");
return err;
}
if (atomic_test_bit(bt_mesh.flags, BT_MESH_COMP_DIRTY) && page < 128) {
sdu.size -= BT_MESH_MIC_SHORT;
err = bt_mesh_comp_read(&sdu, page);
sdu.size += BT_MESH_MIC_SHORT;
} else {
err = bt_mesh_comp_data_get_page_0(&sdu, 0);
if (err < 0) {
LOG_ERR("Unable to get composition page 0");
return err;
}
err = bt_mesh_comp_data_get_page(&sdu, page, 0);
}
if (err) {
LOG_ERR("Failed to get CDP%d, err:%d", page, err);
return err;
}
if (bt_mesh_model_send(model, ctx, &sdu, NULL, NULL)) {

View file

@ -98,13 +98,13 @@ static int cmd_get_comp(const struct shell *sh, size_t argc, char *argv[])
return 0;
}
if (page != 0x00 && page != 0x01 && page != 0x80) {
shell_print(sh, "Got page 0x%02x. No parser available.",
if (page != 0 && page != 1 && page != 128 && page != 129) {
shell_print(sh, "Got page %d. No parser available.",
page);
return 0;
}
if (page != 1) {
if (page == 0 || page == 128) {
err = bt_mesh_comp_p0_get(&comp, &buf);
if (err) {
@ -113,7 +113,8 @@ static int cmd_get_comp(const struct shell *sh, size_t argc, char *argv[])
return 0;
}
shell_print(sh, "Got Composition Data for 0x%04x:", bt_mesh_shell_target_ctx.dst);
shell_print(sh, "Got Composition Data for 0x%04x, page: %d:",
bt_mesh_shell_target_ctx.dst, page);
shell_print(sh, "\tCID 0x%04x", comp.cid);
shell_print(sh, "\tPID 0x%04x", comp.pid);
shell_print(sh, "\tVID 0x%04x", comp.vid);
@ -153,7 +154,7 @@ static int cmd_get_comp(const struct shell *sh, size_t argc, char *argv[])
}
}
if (IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_1) && page == 1) {
if (IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_1) && (page == 1 || page == 129)) {
/* size of 32 is chosen arbitrary, as sufficient for testing purposes */
NET_BUF_SIMPLE_DEFINE(p1_buf, 32);
NET_BUF_SIMPLE_DEFINE(p1_item_buf, 32);
@ -167,7 +168,7 @@ static int cmd_get_comp(const struct shell *sh, size_t argc, char *argv[])
return 0;
}
shell_print(sh,
"Got Composition Data for 0x%04x, page: 0x%02x:",
"Got Composition Data for 0x%04x, page: %d:",
bt_mesh_shell_target_ctx.dst, page);
while (bt_mesh_comp_p1_elem_pull(&buf, &p1_elem)) {