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 #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, void bt_mesh_model_foreach(void (*func)(struct bt_mesh_model *mod,
struct bt_mesh_elem *elem, struct bt_mesh_elem *elem,
bool vnd, bool primary, 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); 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) int bt_mesh_comp_store(void)
{ {
NET_BUF_SIMPLE_DEFINE(buf, BT_MESH_TX_SDU_MAX); NET_BUF_SIMPLE_DEFINE(buf, BT_MESH_TX_SDU_MAX);
int err; int err;
err = bt_mesh_comp_data_get_page_0(&buf, 0); for (int i = 0; i < ARRAY_SIZE(comp_data_pages); i++) {
if (err) { net_buf_simple_reset(&buf);
LOG_ERR("Failed to read composition data: %d", err);
return err; 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); return 0;
if (err) {
LOG_ERR("Failed to store composition data: %d", err);
} else {
LOG_DBG("Stored composition data");
}
return err;
} }
int bt_mesh_comp_change_prepare(void) int bt_mesh_comp_change_prepare(void)
@ -2171,11 +2197,12 @@ static void comp_data_clear(void)
{ {
int err; int err;
err = settings_delete("bt/mesh/cmp"); for (int i = 0; i < ARRAY_SIZE(comp_data_pages); i++) {
if (err) { err = settings_delete(comp_data_pages[i].path);
LOG_ERR("Failed to clear composition data: %d", err); if (err) {
} else { LOG_ERR("Failed to clear CDP%d: %d", comp_data_pages[i].page,
LOG_DBG("Cleared composition data page 128"); err);
}
} }
atomic_clear_bit(bt_mesh.flags, BT_MESH_COMP_DIRTY); 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; 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; size_t original_len = buf->len;
int i;
int err; int err;
if (!IS_ENABLED(CONFIG_BT_SETTINGS)) { if (!IS_ENABLED(CONFIG_BT_SETTINGS)) {
return -ENOTSUP; 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) { if (err) {
LOG_ERR("Failed reading composition data: %d", err); LOG_ERR("Failed reading composition data: %d", err);
return err; return err;
} }
if (buf->len == original_len) { if (buf->len == original_len) {
return -ENOENT; return -ENOENT;
} }
return 0; 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_register(const struct bt_mesh_comp *comp);
int bt_mesh_comp_store(void); 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_store(void);
int bt_mesh_models_metadata_read(struct net_buf_simple *buf, size_t offset); 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_pending_clear(void);
void bt_mesh_comp_data_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_pending_store(void);
void bt_mesh_model_bind_store(struct bt_mesh_model *mod); 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) struct bt_mesh_comp_p1_elem *elem)
{ {
if (buf->len < 6) { 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; return NULL;
} }
size_t elem_size = 0; 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); page = net_buf_simple_pull_u8(buf);
if (page >= 128U && (atomic_test_bit(bt_mesh.flags, BT_MESH_COMP_DIRTY) || if (page >= 129U && IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_1) &&
IS_ENABLED(CONFIG_BT_MESH_RPR_SRV))) { (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; page = 128U;
} else if (page >= 1U && IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_1)) { } else if (page >= 1U && IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_1)) {
page = 1U; 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); bt_mesh_model_msg_init(&sdu, OP_DEV_COMP_DATA_STATUS);
net_buf_simple_add_u8(&sdu, page); 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; sdu.size += BT_MESH_MIC_SHORT;
} else { } else {
err = bt_mesh_comp_data_get_page_0(&sdu, 0); err = bt_mesh_comp_data_get_page(&sdu, page, 0);
if (err < 0) { }
LOG_ERR("Unable to get composition page 0");
return err; 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)) { 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; return 0;
} }
if (page != 0x00 && page != 0x01 && page != 0x80) { if (page != 0 && page != 1 && page != 128 && page != 129) {
shell_print(sh, "Got page 0x%02x. No parser available.", shell_print(sh, "Got page %d. No parser available.",
page); page);
return 0; return 0;
} }
if (page != 1) { if (page == 0 || page == 128) {
err = bt_mesh_comp_p0_get(&comp, &buf); err = bt_mesh_comp_p0_get(&comp, &buf);
if (err) { if (err) {
@ -113,7 +113,8 @@ static int cmd_get_comp(const struct shell *sh, size_t argc, char *argv[])
return 0; 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, "\tCID 0x%04x", comp.cid);
shell_print(sh, "\tPID 0x%04x", comp.pid); shell_print(sh, "\tPID 0x%04x", comp.pid);
shell_print(sh, "\tVID 0x%04x", comp.vid); 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 */ /* size of 32 is chosen arbitrary, as sufficient for testing purposes */
NET_BUF_SIMPLE_DEFINE(p1_buf, 32); NET_BUF_SIMPLE_DEFINE(p1_buf, 32);
NET_BUF_SIMPLE_DEFINE(p1_item_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; return 0;
} }
shell_print(sh, 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); bt_mesh_shell_target_ctx.dst, page);
while (bt_mesh_comp_p1_elem_pull(&buf, &p1_elem)) { while (bt_mesh_comp_p1_elem_pull(&buf, &p1_elem)) {