Bluetooth: Mesh: analyze multicast model rx status

Commit adds analyzing of returned status of element rx.
If at least one element receives multicast message then
access layer will return suceess status.
If option CONFIG_BT_MESH_ACCESS_LAYER_MSG is enabled then
access layer will return success always.
Function bt_mesh_access_recv has been introduced to cover
case when real model statuses should be returned over
oppcode aggregator model despite access returns success.

Signed-off-by: Aleksandr Khromykh <aleksandr.khromykh@nordicsemi.no>
This commit is contained in:
Aleksandr Khromykh 2024-03-19 14:35:24 +01:00 committed by Anas Nashif
commit 7e39db9bce
3 changed files with 31 additions and 2 deletions

View file

@ -697,6 +697,14 @@ config BT_MESH_ACCESS_LAYER_MSG
Bluetooth access layer messages without the need to
instantiate Bluetooth Mesh models.
Please note that Bluetooth Mesh stack stores authentication sequence from
any message that passed over network cache if this option is enabled.
It happens despite the device does not have necessary application keys or
there are unknown model operation codes. It causes the situation when device
will update the replay protection cache for messages those cannot be handled
in the stack. For example, spamming broadcast messages those stack cannot handle
might wear out persistent memory.
config BT_MESH_MODEL_VND_MSG_CID_FORCE
bool "Force vendor model to use the corresponding CID field message"
default y

View file

@ -1545,17 +1545,20 @@ int bt_mesh_model_recv(struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf)
if (index >= dev_comp->elem_count) {
LOG_ERR("Invalid address 0x%02x", ctx->recv_dst);
err = ACCESS_STATUS_INVALID_ADDRESS;
return ACCESS_STATUS_INVALID_ADDRESS;
} else {
const struct bt_mesh_elem *elem = &dev_comp->elem[index];
err = element_model_recv(ctx, buf, elem, opcode);
}
} else {
err = ACCESS_STATUS_MESSAGE_NOT_UNDERSTOOD;
for (index = 0; index < dev_comp->elem_count; index++) {
const struct bt_mesh_elem *elem = &dev_comp->elem[index];
int err_elem;
(void)element_model_recv(ctx, buf, elem, opcode);
err_elem = element_model_recv(ctx, buf, elem, opcode);
err = err_elem == ACCESS_STATUS_SUCCESS ? err_elem : err;
}
}
@ -1566,6 +1569,23 @@ int bt_mesh_model_recv(struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf)
return err;
}
int bt_mesh_access_recv(struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf)
{
int err;
err = bt_mesh_model_recv(ctx, buf);
if (IS_ENABLED(CONFIG_BT_MESH_ACCESS_LAYER_MSG) && msg_cb) {
/* Mesh assumes that the application has processed the message.
* Access layer returns success to trigger RPL update and prevent
* replay attack over application.
*/
err = 0;
}
return err;
}
int bt_mesh_model_send(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *msg,
const struct bt_mesh_send_cb *cb, void *cb_data)

View file

@ -59,6 +59,7 @@ const struct bt_mesh_comp *bt_mesh_comp_get(void);
const struct bt_mesh_model *bt_mesh_model_get(bool vnd, uint8_t elem_idx, uint8_t mod_idx);
int bt_mesh_access_recv(struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf);
int bt_mesh_model_recv(struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf);
int bt_mesh_comp_register(const struct bt_mesh_comp *comp);