We are using nrf52840 as a peripheral, Nordic SDK 15.3.0_59ac345.
We are experiencing issues in the field where users are unable to reconnect with our device from our app on iOS phones. App logs indicate that link encryption is failing because Status: PIN or Key Missing (0x06)
. What follows is my interpretation of what's going on and a potential solution. Looking for feedback from y'all about the problem statement and any better solutions that may exist.
pm_handler_flash_clean (which we run from our register PM event handler)
, keeps a local flag to track that the next flash write succeeded after a garbage collection occurs. If it detects that a flash write after garbage collection fails it assumes that more drastic measures are needed and will mark the oldest peer for deletion and rerun garbage collection, which will result in bond information deletion for the selected peer. What I see happening is a race between multiple instances of flash writes failing because the flash is full (which can be detected synchronously, as apposed to actual flash write attempts).- flash write A starts and fails for flash full
- GC A starts, sets
flash_write_after_gc = false
, successful write after GC will set back to true - flash write B starts and fails for flash full
- GC B detects that
flash_write_after_gc == false
and marks the oldest peer for deletion and then starts - GC A completes
- GC B completes, peer bond information has been deleted
Status: PIN or Key Missing (0x06)
.00> <debug> peer_manager_handler: Event PM_EVT_STORAGE_FULL 00> <warning> peer_manager_handler: Flash storage is full 00> <info> peer_manager_handler: Attempting to clean flash. 00> <debug> peer_manager_handler: Running flash garbage collection. 00> <debug> peer_manager_handler: Event PM_EVT_STORAGE_FULL 00> <warning> peer_manager_handler: Flash storage is full 00> <warning> peer_manager_gcm: Flash full. Could not store data for conn_handle: 0 00> <debug> peer_manager_handler: Event PM_EVT_STORAGE_FULL 00> <warning> peer_manager_handler: Flash storage is full 00> <debug> peer_manager_handler: Event PM_EVT_STORAGE_FULL 00> <warning> peer_manager_handler: Flash storage is full 00> <debug> peer_manager_handler: Event PM_EVT_FLASH_GARBAGE_COLLECTED 00> <debug> peer_manager_handler: Flash garbage collection complete. 00> <debug> peer_manager_handler: Event PM_EVT_FLASH_GARBAGE_COLLECTED 00> <debug> peer_manager_handler: Flash garbage collection complete. 00> <debug> peer_manager_handler: Event PM_EVT_STORAGE_FULL 00> <warning> peer_manager_handler: Flash storage is full 00> <info> peer_manager_handler: Attempting to clean flash. 00> <info> peer_manager_handler: Deleting lowest ranked peer (peer_id: 0) 00> <debug> peer_manager_handler: Event PM_EVT_STORAGE_FULL 00> <warning> peer_manager_handler: Flash storage is full 00> <debug> peer_manager_handler: Event PM_EVT_PEER_DATA_UPDATE_SUCCEEDED 00> <debug> peer_manager_handler: Peer data updated in flash: peer_id: 0, data_id: Local database, action: Update 00> <debug> peer_manager_handler: Event PM_EVT_PEER_DATA_UPDATE_SUCCEEDED 00> <debug> peer_manager_handler: Peer data updated in flash: peer_id: 0, data_id: Local database, action: Update 00> <debug> peer_manager_handler: Event PM_EVT_STORAGE_FULL 00> <warning> peer_manager_handler: Flash storage is full 00> <info> peer_manager_handler: Attempting to clean flash. 00> <debug> peer_manager_handler: Running flash garbage collection. 00> <debug> peer_manager_handler: Event PM_EVT_STORAGE_FULL 00> <warning> peer_manager_handler: Flash storage is full 00> <debug> peer_manager_handler: Event PM_EVT_PEER_DELETE_SUCCEEDED 00> <error> peer_manager_handler: Peer deleted successfully: peer_id: 0 00> <debug> peer_manager_handler: Event PM_EVT_PEER_DELETE_SUCCEEDED 00> <error> peer_manager_handler: Peer deleted successfully: peer_id: 0