diff options
author | Inga Stotland <inga.stotland@intel.com> | 2020-06-30 11:56:15 -0700 |
---|---|---|
committer | Brian Gix <brian.gix@intel.com> | 2020-07-01 12:06:07 -0700 |
commit | e803b54864aa2d222eabc02f4814af9b467de34a (patch) | |
tree | b01c71488ab6807ba2296411ae2df48a0fb91a34 /mesh/model.c | |
parent | 807886eb5717902cd10ff8ad13e91d9200f0549d (diff) | |
download | bluez-e803b54864aa2d222eabc02f4814af9b467de34a.tar.gz |
mesh: Check app model settings of pub/sub support
This adds handling of new options dictionary included with
"Models" and "VendorModels" properties on org.bluez.mesh.Element1
interface.
Supported (optional) dictionary entries:
"Publish" - indicates whether the model supports publication mechanism.
If not present, publication is enabled.
"Subscribe" - indicates whether the model supports subscription mechanism.
If not present, subscriptions are enabled.
If a config message related to subscription state is received for a model
that does not support subscription mechanism, an error code 0x08,
("Not A Subscribe Model") is sent in response.
If a config message related to publication state is received for a model
that does not support publication mechanism, an error code 0x07
("Invalid Publish Parameters") is sent in response.
Diffstat (limited to 'mesh/model.c')
-rw-r--r-- | mesh/model.c | 98 |
1 files changed, 84 insertions, 14 deletions
diff --git a/mesh/model.c b/mesh/model.c index 5ed95afac..afac6ec69 100644 --- a/mesh/model.c +++ b/mesh/model.c @@ -51,6 +51,8 @@ struct mesh_model { struct l_queue *subs; struct l_queue *virtuals; struct mesh_model_pub *pub; + bool sub_enabled; + bool pub_enabled; uint32_t id; uint8_t ele_idx; }; @@ -1097,7 +1099,7 @@ int mesh_model_pub_set(struct mesh_node *node, uint16_t addr, uint32_t id, if (!mod) return status; - if (id == CONFIG_SRV_MODEL || id == CONFIG_CLI_MODEL) + if (!mod->pub_enabled || (mod->cbs && !(mod->cbs->pub))) return MESH_STATUS_INVALID_PUB_PARAM; if (!appkey_have_key(node_get_net(node), idx)) @@ -1134,9 +1136,11 @@ int mesh_model_pub_set(struct mesh_node *node, uint16_t addr, uint32_t id, /* External model */ config_update_model_pub_period(node, mod->ele_idx, id, pub_period_to_ms(period)); - else + else { /* Internal model, call registered callbacks */ - mod->cbs->pub(mod->pub); + if (mod->cbs->pub) + mod->cbs->pub(mod->pub); + } return MESH_STATUS_SUCCESS; } @@ -1150,6 +1154,11 @@ struct mesh_model_pub *mesh_model_pub_get(struct mesh_node *node, uint16_t addr, if (!mod) return NULL; + if (!mod->pub_enabled || (mod->cbs && !(mod->cbs->pub))) + *status = MESH_STATUS_INVALID_PUB_PARAM; + else + *status = MESH_STATUS_SUCCESS; + return mod->pub; } @@ -1171,6 +1180,13 @@ struct mesh_model *mesh_model_new(uint8_t ele_idx, uint32_t id) mod->id = id; mod->ele_idx = ele_idx; mod->virtuals = l_queue_new(); + + /* + * Unless specifically indicated by an app, subscriptions and + * publications are enabled by default + */ + mod->sub_enabled = true; + mod->pub_enabled = true; return mod; } @@ -1318,6 +1334,9 @@ int mesh_model_sub_get(struct mesh_node *node, uint16_t addr, uint32_t id, if (!mod) return status; + if (!mod->sub_enabled || (mod->cbs && !(mod->cbs->sub))) + return MESH_STATUS_NOT_SUB_MOD; + entry = l_queue_get_entries(mod->subs); *size = 0; n = 0; @@ -1358,6 +1377,9 @@ int mesh_model_sub_add(struct mesh_node *node, uint16_t addr, uint32_t id, if (!mod) return status; + if (!mod->sub_enabled || (mod->cbs && !(mod->cbs->sub))) + return MESH_STATUS_NOT_SUB_MOD; + status = add_sub(node_get_net(node), mod, group, is_virt, dst); if (status != MESH_STATUS_SUCCESS) @@ -1381,6 +1403,9 @@ int mesh_model_sub_ovr(struct mesh_node *node, uint16_t addr, uint32_t id, if (!mod) return status; + if (!mod->sub_enabled || (mod->cbs && !(mod->cbs->sub))) + return MESH_STATUS_NOT_SUB_MOD; + subs = mod->subs; virtuals = mod->virtuals; mod->subs = l_queue_new(); @@ -1430,6 +1455,9 @@ int mesh_model_sub_del(struct mesh_node *node, uint16_t addr, uint32_t id, if (!mod) return status; + if (!mod->sub_enabled || (mod->cbs && !(mod->cbs->sub))) + return MESH_STATUS_NOT_SUB_MOD; + if (is_virt) { struct mesh_virtual *virt; @@ -1448,27 +1476,22 @@ int mesh_model_sub_del(struct mesh_node *node, uint16_t addr, uint32_t id, *dst = grp; - if (l_queue_remove(mod->subs, L_UINT_TO_PTR(grp))) + if (l_queue_remove(mod->subs, L_UINT_TO_PTR(grp))) { mesh_net_dst_unreg(node_get_net(node), grp); - if (!mod->cbs) - /* External models */ - config_update_model_subscriptions(node, mod); + if (!mod->cbs) + /* External models */ + config_update_model_subscriptions(node, mod); + } return MESH_STATUS_SUCCESS; } -int mesh_model_sub_del_all(struct mesh_node *node, uint16_t addr, uint32_t id) +static void remove_subs(struct mesh_node *node, struct mesh_model *mod) { - int status; - struct mesh_model *mod; const struct l_queue_entry *entry; struct mesh_net *net = node_get_net(node); - mod = find_model(node, addr, id, &status); - if (!mod) - return status; - entry = l_queue_get_entries(mod->subs); for (; entry; entry = entry->next) @@ -1476,6 +1499,21 @@ int mesh_model_sub_del_all(struct mesh_node *node, uint16_t addr, uint32_t id) l_queue_clear(mod->subs, NULL); l_queue_clear(mod->virtuals, unref_virt); +} + +int mesh_model_sub_del_all(struct mesh_node *node, uint16_t addr, uint32_t id) +{ + int status; + struct mesh_model *mod; + + mod = find_model(node, addr, id, &status); + if (!mod) + return status; + + if (!mod->sub_enabled || (mod->cbs && !(mod->cbs->sub))) + return MESH_STATUS_NOT_SUB_MOD; + + remove_subs(node, mod); if (!mod->cbs) /* External models */ @@ -1677,6 +1715,38 @@ void model_build_config(void *model, void *msg_builder) l_dbus_message_builder_leave_struct(builder); } +void mesh_model_enable_pub(struct mesh_model *mod, bool enable) +{ + mod->pub_enabled = enable; + + if (!mod->pub_enabled && mod->pub) { + if (mod->pub->virt) + unref_virt(mod->pub->virt); + + l_free(mod->pub); + mod->pub = NULL; + } +} + +bool mesh_model_is_pub_enabled(struct mesh_model *mod) +{ + return mod->pub_enabled; +} + +void mesh_model_enable_sub(struct mesh_node *node, struct mesh_model *mod, + bool enable) +{ + mod->sub_enabled = enable; + + if (!mod->sub_enabled) + remove_subs(node, mod); +} + +bool mesh_model_is_sub_enabled(struct mesh_model *mod) +{ + return mod->sub_enabled; +} + void mesh_model_init(void) { mesh_virtuals = l_queue_new(); |