Skip to content

Commit

Permalink
Bluetooth: Mesh: Add option to call update cb on every retransmission
Browse files Browse the repository at this point in the history
A user may want to control message parameters (for example, delay
parameter) on every retransmission of a published message (for example,
see section 1.4.1 of the mesh model specification). This is essential
for lighting messages as time gap between messages retransmitted via
the publish-retransmit mechanism introduces unwanted jitter/pop-corn
when such retransmissions are received by a large 'group' of lights.

This commit adds an option to `struct bt_mesh_model_pub` to make the
access layer call `bt_mesh_model_pub.update` callback on every
retransmission. This also addes few macros and functions that can be
used for further calculations.

Signed-off-by: Pavel Vasilyev <pavel.vasilyev@nordicsemi.no>
  • Loading branch information
PavelVPV authored and jhedberg committed Nov 22, 2021
1 parent f2e45d7 commit 70b0734
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 2 deletions.
10 changes: 10 additions & 0 deletions doc/reference/bluetooth/mesh/access.rst
Expand Up @@ -100,6 +100,16 @@ populate the :c:member:`bt_mesh_model_pub.update` callback. The
message is published, allowing the model to change the payload to reflect its
current state.

By setting :c:member:`bt_mesh_model_pub.retr_update` to 1, the model can
configure the :c:member:`bt_mesh_model_pub.update` callback to be triggered
on every retransmission. This can, for example, be used by models that make
use of a Delay parameter, which can be adjusted for every retransmission.
The :c:func:`bt_mesh_model_pub_is_retransmission` function can be
used to differentiate a first publication and a retransmission.
The :c:macro:`BT_MESH_PUB_MSG_TOTAL` and :c:macro:`BT_MESH_PUB_MSG_NUM` macros
can be used to return total number of transmissions and the retransmission
number within one publication interval.

Extended models
===============

Expand Down
42 changes: 41 additions & 1 deletion include/bluetooth/mesh/access.h
Expand Up @@ -343,6 +343,29 @@ struct bt_mesh_model_op {
*/
#define BT_MESH_PUB_TRANSMIT_INT(transmit) ((((transmit) >> 3) + 1) * 50)

/** @def BT_MESH_PUB_MSG_TOTAL
*
* @brief Get total number of messages within one publication interval including initial
* publication.
*
* @param pub Model publication context.
*
* @return total number of messages.
*/
#define BT_MESH_PUB_MSG_TOTAL(pub) (BT_MESH_PUB_TRANSMIT_COUNT((pub)->retransmit) + 1)

/** @def BT_MESH_PUB_MSG_NUM
*
* @brief Get message number within one publication interval.
*
* Meant to be used inside @ref bt_mesh_model_pub.update.
*
* @param pub Model publication context.
*
* @return message number starting from 1.
*/
#define BT_MESH_PUB_MSG_NUM(pub) (BT_MESH_PUB_TRANSMIT_COUNT((pub)->retransmit) + 1 - (pub)->count)

/** Model publication context.
*
* The context should primarily be created using the
Expand All @@ -356,7 +379,8 @@ struct bt_mesh_model_pub {
uint16_t key:12, /**< Publish AppKey Index. */
cred:1, /**< Friendship Credentials Flag. */
send_rel:1, /**< Force reliable sending (segment acks) */
fast_period:1; /**< Use FastPeriodDivisor */
fast_period:1, /**< Use FastPeriodDivisor */
retr_update:1; /**< Call update callback on every retransmission. */

uint8_t ttl; /**< Publish Time to Live. */
uint8_t retransmit; /**< Retransmit Count & Interval Steps. */
Expand Down Expand Up @@ -386,6 +410,9 @@ struct bt_mesh_model_pub {
* If the callback returns non-zero, the publication is skipped
* and will resume on the next periodic publishing interval.
*
* When @ref bt_mesh_model_pub.retr_update is set to 1,
* the callback will be called on every retransmission.
*
* @param mod The Model the Publication Context belogs to.
*
* @return Zero on success or (negative) error code otherwise.
Expand Down Expand Up @@ -572,6 +599,19 @@ int bt_mesh_model_send(struct bt_mesh_model *model,
*/
int bt_mesh_model_publish(struct bt_mesh_model *model);

/** @brief Check if a message is being retransmitted.
*
* Meant to be used inside the @ref bt_mesh_model_pub.update callback.
*
* @param model Mesh Model that supports publication.
*
* @return true if this is a retransmission, false if this is a first publication.
*/
static inline bool bt_mesh_model_pub_is_retransmission(const struct bt_mesh_model *model)
{
return model->pub->count != BT_MESH_PUB_TRANSMIT_COUNT(model->pub->retransmit);
}

/** @brief Get the element that a model belongs to.
*
* @param mod Mesh model.
Expand Down
11 changes: 10 additions & 1 deletion subsys/bluetooth/mesh/access.c
Expand Up @@ -241,6 +241,15 @@ static void mod_publish(struct k_work *work)

if (pub->count) {
pub->count--;

if (pub->retr_update && pub->update &&
bt_mesh_model_pub_is_retransmission(pub->mod)) {
err = pub->update(pub->mod);
if (err) {
publish_sent(err, pub->mod);
return;
}
}
} else {
/* First publication in this period */
err = pub_period_start(pub);
Expand Down Expand Up @@ -766,7 +775,7 @@ int bt_mesh_model_publish(struct bt_mesh_model *model)
}

/* Account for initial transmission */
pub->count = BT_MESH_PUB_TRANSMIT_COUNT(pub->retransmit) + 1;
pub->count = BT_MESH_PUB_MSG_TOTAL(pub);

BT_DBG("Publish Retransmit Count %u Interval %ums", pub->count,
BT_MESH_PUB_TRANSMIT_INT(pub->retransmit));
Expand Down

0 comments on commit 70b0734

Please sign in to comment.