From a7bb9284208394bc05b404150b881abec4b5d8b6 Mon Sep 17 00:00:00 2001 From: Aleksandr Khromykh Date: Wed, 20 Apr 2022 10:35:44 +0200 Subject: [PATCH] Bluetooth: Mesh: subscription on fixed group addresses There is errata clarification (Errata ID:18700) about subscriptions on fixed group addresses. It is possible to subscribe models on non primary elements on any fixed group address except all nodes address. Devices should be able to receive messages on fixed addresses even if they do not support the feature to which the fixed group address belongs. Signed-off-by: Aleksandr Khromykh --- include/zephyr/bluetooth/mesh/access.h | 3 ++- subsys/bluetooth/mesh/access.c | 3 ++- subsys/bluetooth/mesh/cfg_cli.c | 15 +++++++++------ subsys/bluetooth/mesh/cfg_srv.c | 6 +++--- 4 files changed, 16 insertions(+), 11 deletions(-) diff --git a/include/zephyr/bluetooth/mesh/access.h b/include/zephyr/bluetooth/mesh/access.h index 6bd23887180..f6123b76d17 100644 --- a/include/zephyr/bluetooth/mesh/access.h +++ b/include/zephyr/bluetooth/mesh/access.h @@ -49,7 +49,8 @@ extern "C" { #define BT_MESH_KEY_DEV_ANY 0xfffc #define BT_MESH_ADDR_IS_UNICAST(addr) ((addr) && (addr) < 0x8000) -#define BT_MESH_ADDR_IS_GROUP(addr) ((addr) >= 0xc000 && (addr) <= 0xff00) +#define BT_MESH_ADDR_IS_GROUP(addr) ((addr) >= 0xc000 && (addr) < 0xff00) +#define BT_MESH_ADDR_IS_FIXED_GROUP(addr) ((addr) >= 0xfffc && (addr) < 0xffff) #define BT_MESH_ADDR_IS_VIRTUAL(addr) ((addr) >= 0x8000 && (addr) < 0xc000) #define BT_MESH_ADDR_IS_RFU(addr) ((addr) >= 0xff00 && (addr) <= 0xfffb) diff --git a/subsys/bluetooth/mesh/access.c b/subsys/bluetooth/mesh/access.c index f0d58fe6dfe..3f827642586 100644 --- a/subsys/bluetooth/mesh/access.c +++ b/subsys/bluetooth/mesh/access.c @@ -583,7 +583,8 @@ static bool model_has_dst(struct bt_mesh_model *mod, uint16_t dst) { if (BT_MESH_ADDR_IS_UNICAST(dst)) { return (dev_comp->elem[mod->elem_idx].addr == dst); - } else if (BT_MESH_ADDR_IS_GROUP(dst) || BT_MESH_ADDR_IS_VIRTUAL(dst)) { + } else if (BT_MESH_ADDR_IS_GROUP(dst) || BT_MESH_ADDR_IS_VIRTUAL(dst) || + (BT_MESH_ADDR_IS_FIXED_GROUP(dst) && mod->elem_idx != 0)) { return !!bt_mesh_model_find_group(&mod, dst); } diff --git a/subsys/bluetooth/mesh/cfg_cli.c b/subsys/bluetooth/mesh/cfg_cli.c index 732ab451c8d..d6888d6a91a 100644 --- a/subsys/bluetooth/mesh/cfg_cli.c +++ b/subsys/bluetooth/mesh/cfg_cli.c @@ -1883,7 +1883,7 @@ static int mod_sub(uint32_t op, uint16_t net_idx, uint16_t addr, uint16_t elem_a int bt_mesh_cfg_mod_sub_add(uint16_t net_idx, uint16_t addr, uint16_t elem_addr, uint16_t sub_addr, uint16_t mod_id, uint8_t *status) { - if (!BT_MESH_ADDR_IS_GROUP(sub_addr)) { + if (!BT_MESH_ADDR_IS_GROUP(sub_addr) && !BT_MESH_ADDR_IS_FIXED_GROUP(sub_addr)) { return -EINVAL; } @@ -1895,7 +1895,8 @@ int bt_mesh_cfg_mod_sub_add_vnd(uint16_t net_idx, uint16_t addr, uint16_t elem_a uint16_t sub_addr, uint16_t mod_id, uint16_t cid, uint8_t *status) { - if (!BT_MESH_ADDR_IS_GROUP(sub_addr) || cid == CID_NVAL) { + if ((!BT_MESH_ADDR_IS_GROUP(sub_addr) && !BT_MESH_ADDR_IS_FIXED_GROUP(sub_addr)) || + cid == CID_NVAL) { return -EINVAL; } @@ -1906,7 +1907,7 @@ int bt_mesh_cfg_mod_sub_add_vnd(uint16_t net_idx, uint16_t addr, uint16_t elem_a int bt_mesh_cfg_mod_sub_del(uint16_t net_idx, uint16_t addr, uint16_t elem_addr, uint16_t sub_addr, uint16_t mod_id, uint8_t *status) { - if (!BT_MESH_ADDR_IS_GROUP(sub_addr)) { + if (!BT_MESH_ADDR_IS_GROUP(sub_addr) && !BT_MESH_ADDR_IS_FIXED_GROUP(sub_addr)) { return -EINVAL; } @@ -1926,7 +1927,8 @@ int bt_mesh_cfg_mod_sub_del_vnd(uint16_t net_idx, uint16_t addr, uint16_t elem_a uint16_t sub_addr, uint16_t mod_id, uint16_t cid, uint8_t *status) { - if (!BT_MESH_ADDR_IS_GROUP(sub_addr) || cid == CID_NVAL) { + if ((!BT_MESH_ADDR_IS_GROUP(sub_addr) && !BT_MESH_ADDR_IS_FIXED_GROUP(sub_addr)) || + cid == CID_NVAL) { return -EINVAL; } @@ -1949,7 +1951,7 @@ int bt_mesh_cfg_mod_sub_del_all_vnd(uint16_t net_idx, uint16_t addr, int bt_mesh_cfg_mod_sub_overwrite(uint16_t net_idx, uint16_t addr, uint16_t elem_addr, uint16_t sub_addr, uint16_t mod_id, uint8_t *status) { - if (!BT_MESH_ADDR_IS_GROUP(sub_addr)) { + if (!BT_MESH_ADDR_IS_GROUP(sub_addr) && !BT_MESH_ADDR_IS_FIXED_GROUP(sub_addr)) { return -EINVAL; } @@ -1961,7 +1963,8 @@ int bt_mesh_cfg_mod_sub_overwrite_vnd(uint16_t net_idx, uint16_t addr, uint16_t elem_addr, uint16_t sub_addr, uint16_t mod_id, uint16_t cid, uint8_t *status) { - if (!BT_MESH_ADDR_IS_GROUP(sub_addr) || cid == CID_NVAL) { + if ((!BT_MESH_ADDR_IS_GROUP(sub_addr) && !BT_MESH_ADDR_IS_FIXED_GROUP(sub_addr)) || + cid == CID_NVAL) { return -EINVAL; } diff --git a/subsys/bluetooth/mesh/cfg_srv.c b/subsys/bluetooth/mesh/cfg_srv.c index 6313282a85a..226458bcaa9 100644 --- a/subsys/bluetooth/mesh/cfg_srv.c +++ b/subsys/bluetooth/mesh/cfg_srv.c @@ -1039,7 +1039,7 @@ static int mod_sub_add(struct bt_mesh_model *model, goto send_status; } - if (!BT_MESH_ADDR_IS_GROUP(sub_addr)) { + if (!BT_MESH_ADDR_IS_GROUP(sub_addr) && !BT_MESH_ADDR_IS_FIXED_GROUP(sub_addr)) { status = STATUS_INVALID_ADDRESS; goto send_status; } @@ -1117,7 +1117,7 @@ static int mod_sub_del(struct bt_mesh_model *model, goto send_status; } - if (!BT_MESH_ADDR_IS_GROUP(sub_addr)) { + if (!BT_MESH_ADDR_IS_GROUP(sub_addr) && !BT_MESH_ADDR_IS_FIXED_GROUP(sub_addr)) { status = STATUS_INVALID_ADDRESS; goto send_status; } @@ -1198,7 +1198,7 @@ static int mod_sub_overwrite(struct bt_mesh_model *model, goto send_status; } - if (!BT_MESH_ADDR_IS_GROUP(sub_addr)) { + if (!BT_MESH_ADDR_IS_GROUP(sub_addr) && !BT_MESH_ADDR_IS_FIXED_GROUP(sub_addr)) { status = STATUS_INVALID_ADDRESS; goto send_status; }