Bluetooth: Mesh: Skip publish if update fails

Allow models to skip a periodic publish interval by returning an error
from the publish update callback.

Previously, an error return from publish update would cancel periodic
publishing. This can't be recovered from, and as such, no valid model
implementation could return an error from this callback, and there was
no way to skip a periodic publish.

Signed-off-by: Trond Einar Snekvik <Trond.Einar.Snekvik@nordicsemi.no>
This commit is contained in:
Trond Einar Snekvik 2020-01-15 16:45:11 +01:00 committed by Johan Hedberg
commit 19718fd6da
2 changed files with 16 additions and 5 deletions

View file

@ -424,6 +424,9 @@ struct bt_mesh_model_pub {
* @ref bt_mesh_model_pub.msg with a valid publication * @ref bt_mesh_model_pub.msg with a valid publication
* message. * message.
* *
* If the callback returns non-zero, the publication is skipped
* and will resume on the next periodic publishing interval.
*
* @param mod The Model the Publication Context belogs to. * @param mod The Model the Publication Context belogs to.
* *
* @return Zero on success or (negative) error code otherwise. * @return Zero on success or (negative) error code otherwise.

View file

@ -187,6 +187,14 @@ static int publish_retransmit(struct bt_mesh_model *mod)
return bt_mesh_trans_send(&tx, &sdu, &pub_sent_cb, mod); return bt_mesh_trans_send(&tx, &sdu, &pub_sent_cb, mod);
} }
static void publish_retransmit_end(int err, struct bt_mesh_model_pub *pub)
{
/* Cancel all retransmits for this publish attempt */
pub->count = 0U;
/* Make sure the publish timer gets reset */
publish_sent(err, pub->mod);
}
static void mod_publish(struct k_work *work) static void mod_publish(struct k_work *work)
{ {
struct bt_mesh_model_pub *pub = CONTAINER_OF(work, struct bt_mesh_model_pub *pub = CONTAINER_OF(work,
@ -224,7 +232,10 @@ static void mod_publish(struct k_work *work)
err = pub->update(pub->mod); err = pub->update(pub->mod);
if (err) { if (err) {
BT_ERR("Failed to update publication message"); /* Cancel this publish attempt. */
BT_DBG("Update failed, skipping publish (err: %d)", err);
pub->period_start = k_uptime_get_32();
publish_retransmit_end(err, pub);
return; return;
} }
@ -744,10 +755,7 @@ int bt_mesh_model_publish(struct bt_mesh_model *model)
err = model_send(model, &tx, true, &sdu, &pub_sent_cb, model); err = model_send(model, &tx, true, &sdu, &pub_sent_cb, model);
if (err) { if (err) {
/* Don't try retransmissions for this publish attempt */ publish_retransmit_end(err, pub);
pub->count = 0U;
/* Make sure the publish timer gets reset */
publish_sent(err, model);
return err; return err;
} }