Skip to content

Commit

Permalink
Bluetooth: Mesh: Fix bug DTT spanning multiple elements
Browse files Browse the repository at this point in the history
If a Generic Default Transition Time Server model is not
present on the main element of the model, then the Generic
Default Transition Time Server model instance that is present
on the element with the largest address that is smaller than
the address of the main element of the node shall be used;
if no model instance is present on any element with an address
smaller than the address of the main element, then the Generic
Default Transition Time Server is not supported.

Signed-off-by: Ingar Kulbrandstad <ingar.kulbrandstad@nordicsemi.no>
  • Loading branch information
Balaklaka committed Jun 23, 2023
1 parent 935319a commit bf6d933
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 24 deletions.
2 changes: 1 addition & 1 deletion doc/nrf/libraries/bluetooth_services/mesh/gen_dtt.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
Generic Default Transition Time models
######################################

The Generic Default Transition Time (DTT) models are used to control the transition of any other states on the same element as the DTT Server.
The Generic Default Transition Time (DTT) models are used to control the transition of any other states on any element.
The DTT Client can remotely control the default transition time state of the server.

The DTT models only use native types, and have no common model-specific types.
Expand Down
7 changes: 4 additions & 3 deletions doc/nrf/libraries/bluetooth_services/mesh/gen_dtt_srv.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ Generic Default Transition Time Server
:local:
:depth: 2

The DTT Server provides a common way to specify the state transition time for other models on the same element.
If other generic models on the same element receive state change commands without transition parameters, they will use the default transition time specified by the DTT Server model.
This way, the DTT Server can define a consistent transition time for all states on their elements, without depending on client configurations.
The DTT Server provides a common way to specify the state transition time for other models on any element.
If a DTT Server is not present on the model's element, use the DTT Server model instance that is present on the element with the largest address that is smaller than the address of the given element.
This way, if other generic models on any element receive state change commands without transition parameters, they will use the default transition time specified by the DTT Server model.
The DTT Server can then define a consistent transition time for all states on their elements, without depending on client configurations.

Configuration
=============
Expand Down
2 changes: 2 additions & 0 deletions doc/nrf/releases/release-notes-changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,8 @@ Bluetooth libraries and services

* The :kconfig:option:`BT_MESH_MODEL_SRV_STORE_TIMEOUT` Kconfig option, that is controlling timeout for storing of model states, is replaced by the :kconfig:option:`BT_MESH_STORE_TIMEOUT` Kconfig option.

* Fixed an issue where the :ref:'bt_mesh_dtt_srv_readme' model could not be found for models spanning multiple elements.

Bootloader libraries
--------------------

Expand Down
26 changes: 14 additions & 12 deletions include/bluetooth/mesh/gen_dtt_srv.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,21 +107,18 @@ void bt_mesh_dtt_srv_set(struct bt_mesh_dtt_srv *srv, uint32_t transition_time);
int bt_mesh_dtt_srv_pub(struct bt_mesh_dtt_srv *srv,
struct bt_mesh_msg_ctx *ctx);

/** @brief Find the Generic DTT server in a given element.
/** @brief Find the Generic DTT server over multiple elements.
*
* @param[in] elem Element to find the DTT server in.
* If the DTT Server is not present on the given element of the model, then the
* try to find the DTT Server model instance that is present on the element with
* the largest address that is smaller than the address of the given element.
*
* @param[in] elem Element to start search of the DTT server in.
*
* @return A pointer to the DTT server instance, or NULL if no instance is
* found.
*/
static inline struct bt_mesh_dtt_srv *
bt_mesh_dtt_srv_get(const struct bt_mesh_elem *elem)
{
struct bt_mesh_model *model = bt_mesh_model_find(
elem, BT_MESH_MODEL_ID_GEN_DEF_TRANS_TIME_SRV);

return (struct bt_mesh_dtt_srv *)(model ? model->user_data : NULL);
}
struct bt_mesh_dtt_srv *bt_mesh_dtt_srv_get(const struct bt_mesh_elem *elem);

/** @brief Get the default transition parameters for the given model.
*
Expand All @@ -134,8 +131,13 @@ static inline bool
bt_mesh_dtt_srv_transition_get(struct bt_mesh_model *model,
struct bt_mesh_model_transition *transition)
{
struct bt_mesh_dtt_srv *srv =
bt_mesh_dtt_srv_get(bt_mesh_model_elem(model));
struct bt_mesh_dtt_srv *srv;

if (IS_ENABLED(CONFIG_BT_MESH_DTT_SRV)) {
srv = bt_mesh_dtt_srv_get(bt_mesh_model_elem(model));
} else {
srv = NULL;
}

transition->time = srv ? srv->transition_time : 0;
transition->delay = 0;
Expand Down
21 changes: 21 additions & 0 deletions subsys/bluetooth/mesh/gen_dtt_srv.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <string.h>
#include <bluetooth/mesh/gen_dtt_srv.h>
#include "model_utils.h"
#include "mesh/access.h"

static void encode_status(struct net_buf_simple *buf, uint32_t transition_time)
{
Expand Down Expand Up @@ -188,3 +189,23 @@ int bt_mesh_dtt_srv_pub(struct bt_mesh_dtt_srv *srv,

return bt_mesh_msg_send(srv->model, ctx, &msg);
}

struct bt_mesh_dtt_srv *bt_mesh_dtt_srv_get(const struct bt_mesh_elem *elem)
{
const struct bt_mesh_comp *comp = bt_mesh_comp_get();
uint16_t index;

index = elem->addr - comp->elem[0].addr;
for (int i = index; i >= 0; --i) {
struct bt_mesh_elem *element = &comp->elem[i];

struct bt_mesh_model *model =
bt_mesh_model_find(element, BT_MESH_MODEL_ID_GEN_DEF_TRANS_TIME_SRV);

if (model) {
return (struct bt_mesh_dtt_srv *)(model->user_data);
}
};

return NULL;
}
12 changes: 4 additions & 8 deletions subsys/bluetooth/mesh/scene_srv.c
Original file line number Diff line number Diff line change
Expand Up @@ -820,29 +820,25 @@ const struct bt_mesh_model_cb _bt_mesh_scene_srv_cb = {
static int scene_setup_srv_init(struct bt_mesh_model *model)
{
struct bt_mesh_scene_srv *srv = model->user_data;
const struct bt_mesh_comp *comp = bt_mesh_comp_get();
struct bt_mesh_model *dtt_srv = NULL;
struct bt_mesh_dtt_srv *dtt_srv = NULL;
int err;
int i;

if (!srv) {
return -EINVAL;
}

srv->setup_mod = model;

for (i = model->elem_idx; (i >= 0) && (dtt_srv == NULL); --i) {
struct bt_mesh_elem *elem = &comp->elem[i];

dtt_srv = bt_mesh_model_find(elem, BT_MESH_MODEL_ID_GEN_DEF_TRANS_TIME_SRV);
if (IS_ENABLED(CONFIG_BT_MESH_DTT_SRV)) {
dtt_srv = bt_mesh_dtt_srv_get(bt_mesh_model_elem(model));
}

if (!dtt_srv) {
LOG_ERR("Failed to find Generic DTT Server on element");
return -EINVAL;
}

err = bt_mesh_model_extend(srv->setup_mod, dtt_srv);
err = bt_mesh_model_extend(srv->setup_mod, dtt_srv->model);
if (err) {
return err;
}
Expand Down

0 comments on commit bf6d933

Please sign in to comment.