Bluetooth: Mesh: Fix model publication

Model publication was broken in a couple of ways:

 - The Publish Retransmit State was not taken into account at all
 - Health Server used a single publish state for all elements

To implement Publish Retransmit properly, one has to use a callback to
track when the message has been sent. The problem with the transport
layer sending APIs was that giving a callback would cause the
transport layer to assume that segmentation (with acks) is desired,
which is not the case for Model Publication (unless the message itself
is too large, of course). Because of this, the message sending context
receives a new send_rel ("Send Reliable") boolean member that an app
can use to force reliable sending.

Another challenge with the Publish Retransmit state is that a buffer
is needed for storing the AppKey-encrypted SDU once it has been sent
out for the first time.To solve this, a new new net_buf_simple member
is added to the model publication context. The separate 'msg' input
parameter of the bt_mesh_model_publish() API is removed, since the
application is now expected to pre-fill pub->msg instead.

To help with the publishing API change, the Health Server model gets a
new helper macro for initializing the publishing context with a
right-sized publishing message.

The API for creating Health Server instances is also redesigned since
it was so far using a single model publishing state, which would
result in erratic behavior in case of multiple elements with the
Health Server Model. Now, the application needs to provide a unique
publishing context for each Health Server instance.

The changes are heavily intertwined, so it's not easily possible to
split them into multiple patches, hence the large(ish) patch.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
This commit is contained in:
Johan Hedberg 2017-11-18 10:24:18 +02:00 committed by Johan Hedberg
commit e7bb76e2b6
14 changed files with 358 additions and 185 deletions

View file

@ -131,7 +131,10 @@ struct bt_mesh_msg_ctx {
u16_t addr;
/** Received TTL value. Not used for sending. */
u8_t recv_ttl;
u8_t recv_ttl:7;
/** Force sending reliably by using segment acknowledgement */
u8_t send_rel:1;
/** TTL, or BT_MESH_TTL_DEFAULT for default TTL. */
u8_t send_ttl;
@ -264,7 +267,11 @@ struct bt_mesh_model_pub {
u8_t retransmit; /* Retransmit Count & Interval Steps */
u8_t period; /* Publish Period */
u8_t period_div:4, /* Divisor for the Period */
cred:1; /* Friendship Credentials Flag */
cred:1, /* Friendship Credentials Flag */
count:3; /* Retransmissions left */
/* Buffer containing the publication message */
struct net_buf_simple *msg;
/* Publish callback */
void (*func)(struct bt_mesh_model *mod);
@ -334,13 +341,15 @@ int bt_mesh_model_send(struct bt_mesh_model *model,
/**
* @brief Send a model publication message.
*
* Before calling this function, the user needs to ensure that the model
* publication message ('msg' member of struct bt_mesh_model_pub) contains
* a valid message to be sent.
*
* @param model Mesh (client) Model that's publishing the message.
* @param msg Access Layer message to publish.
*
* @return 0 on success, or (negative) error code on failure.
*/
int bt_mesh_model_publish(struct bt_mesh_model *model,
struct net_buf_simple *msg);
int bt_mesh_model_publish(struct bt_mesh_model *model);
/** Node Composition */
struct bt_mesh_comp {