Bluetooth: Mesh: Refactor Mesh Model Extensions
The existing extension tree does not support all the features that are defined by the specification (e.g. multiple parents). This patch approaches this problem by defining a circular single-linked list of extension models. So for a given model, all models that are on the same list as that model are in some extension relationship with that model. All models on a list represent a single connected component of an extension graph but without defining specific relationships between each pair of models. This list is used to manage a shared subscription list as per the Mesh Profile Specification: ```4.2.4 Subscription List Within an element, each model has a separate instance of a Subscription List, unless the model extends another model on that element. Instances of models that extend other models (i.e., all models within an extension relation tree) shall share a single instance of a Subscription List per element. ``` Signed-off-by: Michał Narajowski <michal.narajowski@codecoup.pl>
This commit is contained in:
parent
6c90860a69
commit
e167ca6539
4 changed files with 80 additions and 92 deletions
|
@ -1145,8 +1145,7 @@ send_status:
|
|||
mod_id, vnd);
|
||||
}
|
||||
|
||||
static enum bt_mesh_walk mod_sub_clear_visitor(struct bt_mesh_model *mod,
|
||||
uint32_t depth, void *user_data)
|
||||
static enum bt_mesh_walk mod_sub_clear_visitor(struct bt_mesh_model *mod, void *user_data)
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_BT_MESH_LOW_POWER)) {
|
||||
bt_mesh_lpn_group_del(mod->groups, ARRAY_SIZE(mod->groups));
|
||||
|
@ -1206,8 +1205,7 @@ static int mod_sub_overwrite(struct bt_mesh_model *model,
|
|||
|
||||
|
||||
if (ARRAY_SIZE(mod->groups) > 0) {
|
||||
bt_mesh_model_tree_walk(bt_mesh_model_root(mod),
|
||||
mod_sub_clear_visitor, NULL);
|
||||
bt_mesh_model_extensions_walk(mod, mod_sub_clear_visitor, NULL);
|
||||
|
||||
mod->groups[0] = sub_addr;
|
||||
status = STATUS_SUCCESS;
|
||||
|
@ -1269,8 +1267,7 @@ static int mod_sub_del_all(struct bt_mesh_model *model,
|
|||
goto send_status;
|
||||
}
|
||||
|
||||
bt_mesh_model_tree_walk(bt_mesh_model_root(mod), mod_sub_clear_visitor,
|
||||
NULL);
|
||||
bt_mesh_model_extensions_walk(mod, mod_sub_clear_visitor, NULL);
|
||||
|
||||
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
|
||||
bt_mesh_model_sub_store(mod);
|
||||
|
@ -1288,8 +1285,7 @@ struct mod_sub_list_ctx {
|
|||
struct net_buf_simple *msg;
|
||||
};
|
||||
|
||||
static enum bt_mesh_walk mod_sub_list_visitor(struct bt_mesh_model *mod,
|
||||
uint32_t depth, void *ctx)
|
||||
static enum bt_mesh_walk mod_sub_list_visitor(struct bt_mesh_model *mod, void *ctx)
|
||||
{
|
||||
struct mod_sub_list_ctx *visit = ctx;
|
||||
int count = 0;
|
||||
|
@ -1365,8 +1361,7 @@ static int mod_sub_get(struct bt_mesh_model *model,
|
|||
|
||||
visit_ctx.msg = &msg;
|
||||
visit_ctx.elem_idx = mod->elem_idx;
|
||||
bt_mesh_model_tree_walk(bt_mesh_model_root(mod), mod_sub_list_visitor,
|
||||
&visit_ctx);
|
||||
bt_mesh_model_extensions_walk(mod, mod_sub_list_visitor, &visit_ctx);
|
||||
|
||||
send_list:
|
||||
if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
|
||||
|
@ -1425,8 +1420,7 @@ static int mod_sub_get_vnd(struct bt_mesh_model *model,
|
|||
|
||||
visit_ctx.msg = &msg;
|
||||
visit_ctx.elem_idx = mod->elem_idx;
|
||||
bt_mesh_model_tree_walk(bt_mesh_model_root(mod), mod_sub_list_visitor,
|
||||
&visit_ctx);
|
||||
bt_mesh_model_extensions_walk(mod, mod_sub_list_visitor, &visit_ctx);
|
||||
|
||||
send_list:
|
||||
if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
|
||||
|
@ -1639,8 +1633,7 @@ static int mod_sub_va_overwrite(struct bt_mesh_model *model,
|
|||
|
||||
status = bt_mesh_va_add(label_uuid, &sub_addr);
|
||||
if (status == STATUS_SUCCESS) {
|
||||
bt_mesh_model_tree_walk(bt_mesh_model_root(mod),
|
||||
mod_sub_clear_visitor, NULL);
|
||||
bt_mesh_model_extensions_walk(mod, mod_sub_clear_visitor, NULL);
|
||||
mod->groups[0] = sub_addr;
|
||||
|
||||
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue