diff --git a/subsys/bluetooth/mesh/access.c b/subsys/bluetooth/mesh/access.c index 0a7a54f62d6..c022eedbadc 100644 --- a/subsys/bluetooth/mesh/access.c +++ b/subsys/bluetooth/mesh/access.c @@ -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; } diff --git a/subsys/bluetooth/mesh/access.h b/subsys/bluetooth/mesh/access.h index 43d5ad43913..a7d3ffe5865 100644 --- a/subsys/bluetooth/mesh/access.h +++ b/subsys/bluetooth/mesh/access.h @@ -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); diff --git a/subsys/bluetooth/mesh/cfg_cli.c b/subsys/bluetooth/mesh/cfg_cli.c index 600b5bb8c50..a5ad80193f3 100644 --- a/subsys/bluetooth/mesh/cfg_cli.c +++ b/subsys/bluetooth/mesh/cfg_cli.c @@ -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; diff --git a/subsys/bluetooth/mesh/cfg_srv.c b/subsys/bluetooth/mesh/cfg_srv.c index a86096550b0..2fba9360206 100644 --- a/subsys/bluetooth/mesh/cfg_srv.c +++ b/subsys/bluetooth/mesh/cfg_srv.c @@ -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)) { diff --git a/subsys/bluetooth/mesh/shell/cfg.c b/subsys/bluetooth/mesh/shell/cfg.c index 9843bece328..d47f04bcc00 100644 --- a/subsys/bluetooth/mesh/shell/cfg.c +++ b/subsys/bluetooth/mesh/shell/cfg.c @@ -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)) {