Bluetooth: Mesh: Rework publication timer

Periodic publication would previously build and send the first
publication inside the bt_mesh_model_pub() function, before cancelling
and rescheduling the next publication. The timer handler would only
handle retransmissions, and would abandon the rest of the publication
event if one of the packets failed to send.

This design has three issues:
- If the initial timer cancel fails, the publication would interfer with
  the periodic publication management, which might skip an event or
  send too many packets.
- If any of the messages fail to publish, the full publication event
  would be abandoned. This is not predictable or expected from the API.
- bt_mesh_model_pub() required 384 bytes of stack to build the message,
  which has to be factored into all calling threads.

This patch moves all transmission into the publication timer by
replacing k_work_cancel with a single k_work_reschedule(K_NO_WAIT). It
also changes the error recovery behavior to attempt to finish the full
publication event even if some of the transmissions fail.

Split out from #33782.

Signed-off-by: Trond Einar Snekvik <Trond.Einar.Snekvik@nordicsemi.no>
This commit is contained in:
Trond Einar Snekvik 2021-04-15 12:28:20 +02:00 committed by Carles Cufí
commit 820cfc52ad
4 changed files with 100 additions and 121 deletions

View file

@ -340,17 +340,17 @@ struct bt_mesh_model_pub {
/** The model the context belongs to. Initialized by the stack. */
struct bt_mesh_model *mod;
uint16_t addr; /**< Publish Address. */
uint16_t key:12, /**< Publish AppKey Index. */
cred:1, /**< Friendship Credentials Flag. */
send_rel:1; /**< Force reliable sending (segment acks) */
uint16_t addr; /**< Publish Address. */
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 */
uint8_t ttl; /**< Publish Time to Live. */
uint8_t retransmit; /**< Retransmit Count & Interval Steps. */
uint8_t period; /**< Publish Period. */
uint8_t period_div:4, /**< Divisor for the Period. */
fast_period:1,/**< Use FastPeriodDivisor */
count:3; /**< Retransmissions left. */
count:4; /**< Transmissions left. */
uint32_t period_start; /**< Start of the current period. */
@ -381,7 +381,7 @@ struct bt_mesh_model_pub {
int (*update)(struct bt_mesh_model *mod);
/** Publish Period Timer. Only for stack-internal use. */
struct k_delayed_work timer;
struct k_work_delayable timer;
};
/** @def BT_MESH_MODEL_PUB_DEFINE