From 5d5706e785275a160d6ec6416f69289d01db17b7 Mon Sep 17 00:00:00 2001 From: Rich Barlow Date: Mon, 5 Aug 2019 17:16:20 +0100 Subject: [PATCH] Bluetooth: Mesh: LPN: Remove msg from cache on rejection When in Low Power mode an LPN may receive messages sent by nodes other than its friend during its brief receive window. These messages get rejected by the transport layer. At some point in the future the LPN will receive these messages from its friend, however they will have already been added to the network message cache earlier. When the transport layer rejects a message due to it being received from a non-friend node while in Low Power mode it must be removed from the network message cache so that it can be correctly received from its friend in the future. Fixes #17809 Signed-off-by: Rich Barlow --- subsys/bluetooth/mesh/net.c | 17 +++++++++++++++-- subsys/bluetooth/mesh/net.h | 1 + 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/subsys/bluetooth/mesh/net.c b/subsys/bluetooth/mesh/net.c index b2f2c3d3585..07ca58f9876 100644 --- a/subsys/bluetooth/mesh/net.c +++ b/subsys/bluetooth/mesh/net.c @@ -137,7 +137,8 @@ static bool msg_cache_match(struct bt_mesh_net_rx *rx, } /* Add to the cache */ - msg_cache[msg_cache_next++] = hash; + rx->msg_cache_idx = msg_cache_next++; + msg_cache[rx->msg_cache_idx] = hash; msg_cache_next %= ARRAY_SIZE(msg_cache); return false; @@ -1323,7 +1324,19 @@ void bt_mesh_net_recv(struct net_buf_simple *data, s8_t rssi, rx.local_match = (bt_mesh_fixed_group_match(rx.ctx.recv_dst) || bt_mesh_elem_find(rx.ctx.recv_dst)); - bt_mesh_trans_recv(&buf, &rx); + /* The transport layer has indicated that it has rejected the message, + * but would like to see it again if it is received in the future. + * This can happen if a message is received when the device is in + * Low Power mode, but the message was not encrypted with the friend + * credentials. Remove it from the message cache so that we accept + * it again in the future. + */ + if (bt_mesh_trans_recv(&buf, &rx) == -EAGAIN) { + BT_WARN("Removing rejected message from Network Message Cache"); + msg_cache[rx.msg_cache_idx] = 0ULL; + /* Rewind the next index now that we're not using this entry */ + msg_cache_next = rx.msg_cache_idx; + } /* Relay if this was a group/virtual address, or if the destination * was neither a local element nor an LPN we're Friends for. diff --git a/subsys/bluetooth/mesh/net.h b/subsys/bluetooth/mesh/net.h index a4ff4477fdb..da953db0dc6 100644 --- a/subsys/bluetooth/mesh/net.h +++ b/subsys/bluetooth/mesh/net.h @@ -268,6 +268,7 @@ struct bt_mesh_net_rx { net_if:2, /* Network interface */ local_match:1, /* Matched a local element */ friend_match:1; /* Matched an LPN we're friends for */ + u16_t msg_cache_idx; /* Index of entry in message cache */ }; /* Encoding context for Network/Transport data */