BLE Bond info is lost when Bangle.JS 2 is turned off #6217
Replies: 1 comment
-
Posted at 2023-09-11 by @gfwilliams Hi, thanks for digging into this - which firmware version do you have in your Bangle at the moment? Just to check though, you are releasing the button on the Bangle as soon as the screen lights up, and not keeping holding it down? I know we have some code which deletes all bonded peers if you boot while holding the button: https://github.com/espruino/Espruino/blob/master/targets/nrf5x/bluetooth.c#L2239-L2260 That's done so that you can't get in the position where your Bangle.js is permanently unconnectable. Posted at 2023-09-11 by user156416 My bangle is on 2v19. I released the button as short as possible for it to still register a power on, releasing right as the "CHECK STORAGE" and "BOOTING" messages appear and the bond is still forgotten. I am not exactly sure when this code is executed and the buttons are polled for the reset, but judging from the comments and macros this was designed to check if ALL buttons are held down, in this case the Bangle 2 only has 1 so it fulfills that condition. I know this is Espruino code not specific to the Bangle, but the bangle also has the Recovery menu that appears to be triggered by holding the button during startup. I think that would be a good place to add a "Clear Bonds" option. I also think it would be good to add some granular control over bonds to the NRF class such as listing and removing individual ones, and then later on adding them to the bluetooth menu in settings app so regular users can manage all the devices their watch is bonded to. I would like to help contribute these features to make the watch a bit more secure for everyone, I have some embedded experience, but I've never written an interpreter before and am not sure what files I should be looking at. Posted at 2023-09-13 by @gfwilliams Hi - well, that is a strange one. As long as you release the button when you're on the blocky text screen (the bootloader) before or about the same time as As you say adding an option into the recovery menu instead seems like a smarter idea - but that menu only got added in the 2v19 last week so it's pretty new. PRs for this kind of stuff would be great! The fact it's an interpreter shouldn't be a big deal as you won't really go near that code. The code itself is at https://github.com/espruino/Espruino and you can build with https://github.com/espruino/Espruino/blob/master/README_Building.md There's some info on extending Espruino at https://www.espruino.com/Extending+Espruino+1#add-function-source-in-c - you don't need to make a new file, just add to And you can see how existing stuff works if you head to the reference at https://www.espruino.com/Reference#NRF then find a function you're interested in. You can then click the ⇒ link in the title and it'll bring you to where the function is defined in the code Posted at 2023-09-13 by user156416 I did it again and can confirm I definitely released the button before I will try and contribute some more wrapped bond management functions but I am a little scared to flash my bangle as I do use it as my watch. Would I just use BLE DFU mode to test my builds on it? Would the bootloader be reflashed as well or does it just stay in place as other regions of flash are overwritten? I am a bit worried about wearing out the flash memory or getting it into an unusable state and having to open it up to reflash. Posted at 2023-09-14 by @fanoush If you talk about Bangle 2 then there is no need to open it to reflash, SWD is right there on the back of the watch. Posted at 2023-09-14 by @fanoush As for FDS - it is used. Normally there are 2 blocks reserved for it, it is the number 2 in this line And the location is right below the bootloader, here Posted at 2023-09-14 by @gfwilliams As mentioned, on Bangle.js 2 we use external flash so we don't touch internal, but even when we do for other boards there is no overlap. It might be worth checking the contents of the FD pages - 2x 4096 byte pages, starting at However I just tested and bonding isn't reset for me...
So I think something else must be broken in your case? Posted at 2023-09-14 by @fanoush
the bootloader is at 0xf7000 not 0xf8(?) https://github.com/espruino/Espruino/blob/master/targetlibs/nrf5x_15/nrf5x_linkers/secure_bootloader_gcc_nrf52.ld#L8
Was expecting that the code here does it Posted at 2023-09-14 by @gfwilliams ahh sorry, forgot about that - so yes, once page further behind... Posted at 2023-09-16 by user156416 If it was retaining the bonds the whitelist would be able to resolve the addresses after a reboot and it cannot. Please try this:
EDIT: Would this code be correct for dumping the 2 pages?
EDIT 2: If I've done the code above correctly, I can confirm that the FDS pages don't get cleared on reboot which is what should be happening according to Gordon. Something else must be the problem, perhaps somewhere in the whitelist code. I will post more findings soon, I really want to get to the bottom of this. Posted at 2023-09-17 by @fanoush Reboot is almost like power off regarding starting of the firmware but power off turns off also the the RAM (most probably, it is configurable). So if something regarding bond info is stored in RAM it is lost. However since static data defined is C source that goes to RAM is reinitialized and bss section is cleared every startup it must be something else - like special linker section just for this. Maybe this can be tested by keeping the RAM on when doing 'power off' just checked and there are actually two methods -off and softOff not sure which one is used Has the bonding info some time validity so it can be invalid because time gets reset to 1970? Posted at 2023-09-17 by @fanoush And btw the softOff would be enough for your habit of turning it off so often, the real off makes sense if putting it away for several months. Maybe the RAM can be kept on by poking the registers EDIT: they are protected, and RAM is indeed set to be turned off too
to enable RAM retention in OFF mode and then you can try to power it off if it makes a difference. Copy paste (ctrl+v) whole block when connected to watch via IDE https://www.espruino.com/ide/ Posted at 2023-09-17 by @fanoush Oh, I just tried Posted at 2023-09-17 by @fanoush Sorry for a lot of noise. Maybe you said that not only 'turn off' but every reboot actually breaks it? Then it is not the RAM. Or it is, but application startup clears it too. Maybe I see something similar or related. In Chrome on Linux when I try to connect via webide it works and device is remembered in the list. Then I can disconnect and reconnect many times just fine. However if I reboot the watch the remembered item in the connect window stops working and I need to search for the watch again via first EDIT: Chrome in Linux or the Bluez stack probably adds some of its own issues so it is not good example or benchmark. When trying more it has issues even when i turn BLE off in watch settings, then when turning BLE back on I see 'Bluetooth Device is no longer in range.' and it does not come back, I need to search again. The error message I mentioned earlier that happens after reboot is reported as "NetworkError: Connection Error: Connection attempt failed.' Posted at 2023-09-17 by @fanoush Anyway so far that was all without bonding. I tried 'pairing' the device in linux in Bluetooth devices panel and this seem to create bond. Here is the interesting part stored in the page below bootloader. I dump everything via
The first page is very similar and does not change.
Also I noticed security status shows
so there is encrypted true, bonded true. Then I rebooted device and reconnected and it changed into
I still get bonded, encrypted connection but there is another short record added.
Then I removed device on linux side so the bonding got lost on linux side and after reconnection the stored data were still the same however the encryption was turned off
no record was added on this new connection. It still says bonded.
So for me reboot does not clear anything, only every new connection add some extra record there (maybe connection encryption keys?). Also clearing bonding from linux side does not change bonding info in Bangle at all. New bonding invalidates previous - it can be seen previous records are modified when next is written so new bonding clears something in the first one. When it works the connection is encrypted and rebooting watch does not break this, reconnecting after reboot keeps it still encrypted. Posted at 2023-09-18 by @gfwilliams Ok, so I'd be pretty sure that actually all the bonding info stays in place after a reboot. @user156416 so you actually checked what I said, and Android reported it was bonded? Because I'd have thought that even if Android remembered it was bonded, if the bonds were erased on the Bangle then it would refuse to connect. So I think the issue is probably the very recently added (code for it is at https://github.com/espruino/Espruino/blob/cfbc4040dac6a7881e3465f60adc4dd8a1e45b85/targets/nrf5x/bluetooth.c#L3654-L3673) Maybe you could try calling it from the IDE along with NRF.getSecurityStatus() after a reboot (you can do remote access from a desktop via the App Loader in Gadgetbridge). I would imagine that if bonded, If so, perhaps while the peer info is all saved to storage, maybe the peer manager doesn't actually load it on boot, so |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Posted at 2023-09-11 by user156416
I've been wanting to use the whitelist with my Bangle as I don't particularly like leaving my devices unsecured. I am aware of the pin option but I would like to make the whitelist work. I've noticed people mention having issues on Android devices due to the apparently randomized MAC addresses. I have found the proper way to add these addresses to the whitelist but the bond info seems to be lost when the watch is turned off (through Settings>Utils>Turn Off)
My Android uses private resolvable addresses when connecting with Bangle.JS Gadgetbridge (nRF Connect seems to use my real public address, so the privacy option seems to be per app?). Private resolvable addresses can be resolved by bonded devices to obtain the public address.
If you bond to the Bangle while the whitelist is OFF, the Bangle can now resolve the addresses. You can now add your device to the whitelist by disconnecting (NOT removing the bond), selecting "Add Device", and connecting by tapping the Bangle card in Gadgetbridge.
Tapping the new whitelist entry you should see "XX:XX:XX:XX:XX:XX public (resolved)" with your unchanging public address. You can now connect and disconnect from the Bangle any number of times with the whitelist on as long as you don't turn it off.
Adding to the whitelist without bonding first will result in "XX:XX:XX:XX:XX:XX private-resolvable" being added to the list with a randomized address, as the Bangle does not have the IRK needed to resolve the public address.
I usually turn my Bangle off when it's off my wrist. I confirmed that the Bangle is unable to resolve addresses after a reboot by writing down and trying to resolve one of my phone's generated public-resolvable addresses using NRF.resolveAddress(). Before the reboot it resolves fine, but after the reboot it returns undefined meaning the address cannot be resolved.
I am not entirely sure, but this seems like it could be a firmware issue with the Nordic Peer Manager not successfully storing or loading bond keys and information from flash.
Beta Was this translation helpful? Give feedback.
All reactions