Skip to content

Commit 953f8ee

Browse files
PavelVPVcarlescufi
authored andcommitted
Bluetooth: Mesh: Fix RPL fragmentation
`bt_mesh_rpl_check` stops iterating `replay_list` if either it found an entry with the requested source address or unassigned address. When IV index updated, `bt_mesh_rpl_reset` is called. It will set `old_iv` to 1 for all entries with fresh IV index and remove entries with old IV index. If the entries with old IV index are mixed with other entries, this will cause fragmentation of `replay_list`. The next time `bt_mesh_rpl_check` is called, it may stop iterating `replay_list` earlier than it should because it will meet an empty entry before it iterates over all entries in the list. This commit does defragmentatino of `replay_list` on every `bt_mesh_rpl_reset` by shiting existing entries to the vacated places. Signed-off-by: Pavel Vasilyev <[email protected]>
1 parent 4ef13f7 commit 953f8ee

File tree

1 file changed

+14
-3
lines changed
  • subsys/bluetooth/mesh

1 file changed

+14
-3
lines changed

subsys/bluetooth/mesh/rpl.c

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -200,12 +200,13 @@ static struct bt_mesh_rpl *bt_mesh_rpl_alloc(uint16_t src)
200200

201201
void bt_mesh_rpl_reset(void)
202202
{
203-
int i;
203+
int shift = 0;
204+
int last = 0;
204205

205206
/* Discard "old old" IV Index entries from RPL and flag
206207
* any other ones (which are valid) as old.
207208
*/
208-
for (i = 0; i < ARRAY_SIZE(replay_list); i++) {
209+
for (int i = 0; i < ARRAY_SIZE(replay_list); i++) {
209210
struct bt_mesh_rpl *rpl = &replay_list[i];
210211

211212
if (rpl->src) {
@@ -215,15 +216,25 @@ void bt_mesh_rpl_reset(void)
215216
} else {
216217
(void)memset(rpl, 0, sizeof(*rpl));
217218
}
219+
220+
shift++;
218221
} else {
219222
rpl->old_iv = true;
220223

224+
if (shift > 0) {
225+
replay_list[i - shift] = *rpl;
226+
}
227+
221228
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
222-
schedule_rpl_store(rpl, true);
229+
schedule_rpl_store(&replay_list[i - shift], true);
223230
}
224231
}
232+
233+
last = i;
225234
}
226235
}
236+
237+
(void) memset(&replay_list[last - shift + 1], 0, sizeof(struct bt_mesh_rpl) * shift);
227238
}
228239

229240
static int rpl_set(const char *name, size_t len_rd,

0 commit comments

Comments
 (0)