lancaster-university / codal-microbit-v2

CODAL target for the micro:bit v2.x series of devices
MIT License
43 stars 52 forks source link

Is it possible to store ~30 bonds rather than just 5? #289

Open jaustin opened 1 year ago

jaustin commented 1 year ago

@martinwork as I understand it, right now we store only 4 bonds and after the 4th bond we overwrite the least-recently-made bond. ( https://github.com/lancaster-university/codal-microbit-v2/blob/6c1433e877e570f9958c1edab77062d4ed9220fd/source/bluetooth/MicroBitBLEManager.cpp#L394 )

Can you easily estimate how much flash we'd need to store ~30 bonds? This would reduce the liklihood of encountering the need to un-bond from the iOS app screen.

martinwork commented 1 year ago

@jaustin Using fd_stat, https://github.com/microbit-foundation/codal-microbit-nrf5sdk/blob/ef4662e13875a7b03e7296d7ac24a2b4d231f323/nRF5SDK/components/libraries/fds/fds.h#L226

It looks like a pairing needs 60 bytes, but only consumes 47 or 48 bytes after garbage collection.

So it appears, 15 - 20 pairings is possible within the current FDS space. I don't know if more bonds means more RAM.

I think the need to forget in Settings/Bluetooth also arises if a flash is attempted in pairing mode before pairing.

After USB flash
words_used 2
largest_contig 1022
freeable_words 0

After pairing
words_used 59
largest_contig 965
freeable_words 11

After another pairing
words_used 120
largest_contig 904
freeable_words 26

After garbage collection
words_used 94
largest_contig 930
freeable_words 0
jaustin commented 1 year ago

So it appears, 15 - 20 pairings is possible within the current FDS space. I don't know if more bonds means more RAM.

@martinwork could you please make a PR for CODAL that allows this larger number of pairings?

I think the need to forget in Settings/Bluetooth also arises if a flash is attempted in pairing mode before pairing.

I don't understand this - what circumstances would someone be able to try to flash before pairing? Doesn't the app ensure pairing happens first? (And if not, couldn't it do that by trying to read a characteristic that requires bonding to force the phone to bond?)

martinwork commented 1 year ago

After running a few of the tests below, I noticed that iOS Settings/Bluetooth was listing both my micro:bits as simply "BBC micro:bit". Forgetting a pairing, would be a chore if there were a class set of pairings.

I think the need to forget in Settings/Bluetooth also arises if a flash is attempted in pairing mode before pairing.

Yes, sorry, I can't make that happen as I remembered it now. Problems can only arise if the micro:bit has previously been paired in the app, so it can be chosen.

1) Using pairing mode to flash when micro:bit has lost it's pairing information, the "wants to pair" dialogue appears, and both V1 and V2 seem to create a good pairing but disconnect showing the tick, so you have to Retry the flash.

2) If micro:bit has full BLE support and pairing information, but iOS has forgotten the pairing, you can flash without using pairing mode. This seems to work with V2, With V1, flashing worked but the pairing information was not saved. Fortunately iOS hadn't stored the pairing either, so I just get the "wants to pair" dialogue each time I flash.

I suspect iOS or app changes may have affected how one of the above works for V1 and/or V2, such that it is different from how I remember it.

I think reading any of the current characteristics initiates pairing, and the "wants to pair" dialogue has to be answered before the app gets to know anything. Maybe add a characteristic with open security?

The sudden appearance of "wants to pair" could make you think you must put micro:bit into pairing mode.

After some further tests, I retried 1). V2 seemed OK but V1 doesn't seem to want to work now. Maybe I have triggered a V1 bug?

I'll make the PR.

jaustin commented 1 year ago

@martinwork the name "BBC micro:bit" vs "BBC micro:bit [vavav]" - is this about whether the iPad last saw the micro:bit as CODAL or as the bootloader?

I looked at where I thought the bootloader would be setting the device name and found this https://github.com/microbit-foundation/v2-bootloader/blob/4215a2beb79e30f9c1435965235512353fcd4c9a/testapp/main.c#LL90C64-L90C64

Which surprises me... can that be right?

Either way, on my iPad I have two paired "BBC micro:bit" devices and two paired "BBC micro:bit [xxxxx]" so it would be good to find out why we get the less detailed one so we can help people removing bonds more easily.

martinwork commented 1 year ago

@jaustin The link to "Nordic buttonless" is in the test app, so not part of the bootloader.

If it last saw the DFU, it may say "DfuTarg". https://github.com/microbit-foundation/v2-bootloader/blob/4215a2beb79e30f9c1435965235512353fcd4c9a/bootloader/microbit/config/sdk_config.h#L1179

[vavav] is present if the last connection was in pairing mode or if using open security.

The V2 name is built here https://github.com/lancaster-university/codal-microbit-v2/blob/master/source/bluetooth/MicroBitBLEManager.cpp#L266 enableBonding is true in pairing mode https://github.com/lancaster-university/codal-microbit-v2/blob/master/model/MicroBit.cpp#L273 https://github.com/lancaster-university/codal-microbit-v2/blob/master/model/MicroBit.cpp#L283

V1 is similar but the name is built in a different place for pairing mode and open security. https://github.com/lancaster-university/microbit-dal/blob/master/source/bluetooth/MicroBitBLEManager.cpp#L649 https://github.com/lancaster-university/microbit-dal/blob/master/source/bluetooth/MicroBitBLEManager.cpp#L305

jaustin commented 1 year ago

So @martinwork then do we have any idea what generates the instances without the friendly name in the iOS settings?

[vavav] is present if the last connection was in pairing mode or if using open security. ... does this mean that once we're bonded we don't have the friendly name? Or is it when the bluetooth extension is used?

martinwork commented 1 year ago

I was thinking that [vavav] isn't present when the last connection was to application mode, but maybe this explains it. https://developer.apple.com/documentation/corebluetooth/cbperipheral/1519029-name?language=objc "A peripheral may have two different name types: one that the device advertises and another that the device publishes in its database as its Bluetooth low energy Generic Access Profile (GAP) device name. If a peripheral has both types of names, this property returns its GAP device name."

microbit-carlos commented 1 year ago

PR https://github.com/lancaster-university/codal-microbit-v2/pull/299 has been merged and will be included in tag v0.2.58, so we can test increasing the number of bonds directly from MakeCode.

We'll keep this issue open to do some tests and figure out how many bonds we can reliably save and if we'd like to change the default.

microbit-carlos commented 1 year ago

@martinwork could you create a MakeCode programme that changes the number of bonds to the theoretical maximum in this test MakeCode instance? (from PR https://github.com/microsoft/pxt-microbit/pull/5319) https://makecode.microbit.org/_dXM2go8TLa2H (Edit: The above URL was a copy/paste mistake, the correct MakeCode deployment link is: https://makecode.microbit.org/app/3b2384609fcdbcba5e83bf3e8d6824443dc0057a-f01d24e0bf)

We can send that hex to a user that might be able to test this. I assume all they need to do is flash this into a micro:bit and then pair with as many devices as possible? Is the bonding data circular? Or would it just stop bonding when running out of memory?

martinwork commented 1 year ago

Here is a share URL for 15 bonds. Check the "on start" serial output to confirm the config values are set.

https://makecode.microbit.org/_17Mcw8VKWf1x

This hex was built in https://makecode.microbit.org/app/3b2384609fcdbcba5e83bf3e8d6824443dc0057a-f01d24e0bf

microbit-datalogger-15bonds.zip

Using separate codal/microbit-dal settings in "Edit Settings as Text" does not seem to work.

I'm wondering if it might be possible to write a program that artificially adds bonds, to test for the possible maximum.

Details...

https://makecode.microbit.org/_dXM2go8TLa2H

I don't understand what that project is for. Anyway, I imported it to https://makecode.microbit.org/app/3b2384609fcdbcba5e83bf3e8d6824443dc0057a-f01d24e0bf added cpptest extension, whose function "one" dumps the config values to serial, added the datalogger extension and copied the code from https://github.com/lancaster-university/codal-microbit-v2/pull/299#issuecomment-1665404226, edited the settings text as below and built it using https://makecode.microbit.org/app/3b2384609fcdbcba5e83bf3e8d6824443dc0057a-f01d24e0bf

Here is the share URL https://makecode.microbit.org/_8bx0ag7vJ18p

But that doesn't set the config values. I tried all the usual steps (and some extras!) to get it to rebuild with the new configs, but it would not work. I tried it without the empty microbit-dal section. Eventually I reverted to the form without separate codal/microbit-dal settings.

    "yotta": {
        "config": {
            "MICROBIT_BLE_UTILITY_SERVICE": "1",
            "MICROBIT_BLE_UTILITY_SERVICE_PAIRING": "1",
            "MICROBIT_BLE_MAXIMUM_BONDS": "15"
        }
    }

which worked straight away. I suspect that it seemed the separate settings were working before because I had just built projects without.

{
    "name": "datalogger-15bonds",
    "description": "",
    "dependencies": {
        "core": "*",
        "radio": "*",
        "microphone": "*",
        "cpptest": "github:martinwork/pxt-cpp#v0.0.4",
        "datalogger": "*"
    },
    "files": [
        "main.blocks",
        "main.ts",
        "README.md"
    ],
    "targetVersions": {
        "branch": "codal-v0.2.56-beta",
        "commits": "https://github.com/microsoft/pxt-microbit/commits/d2d935e869fe15d7682e8d2f2a9916c711bef9f4",
        "target": "6.1.4",
        "pxt": "9.1.6"
    },
    "preferredEditor": "blocksprj",
    "yotta": {
        "config": {
            "codal": {
                "MICROBIT_BLE_UTILITY_SERVICE": "1",
                "MICROBIT_BLE_UTILITY_SERVICE_PAIRING": "1",
                "MICROBIT_BLE_MAXIMUM_BONDS": "15"
            },
            "microbit-dal": {}
        }
    }
}
martinwork commented 1 year ago

CODAL should forget the oldest bond when it reaches the maximum. https://github.com/lancaster-university/codal-microbit-v2/blob/master/source/bluetooth/MicroBitBLEManager.cpp#L394

microbit-carlos commented 1 year ago

Details...

https://makecode.microbit.org/_dXM2go8TLa2H

I don't understand what that project is for.

Sorry Martin! I incorrectly thought I had the MakeCode CI deployment URL copied and ended up pasting whatever random URL I had in the clipboard. I've edited the original message to cross-out the old link and add the correct one https://makecode.microbit.org/app/3b2384609fcdbcba5e83bf3e8d6824443dc0057a-f01d24e0bf

You have used the right link from the PR though 👍

martinwork commented 1 year ago

It was lucky that lead me to rebuild the example and discover it wasn't working!

martinwork commented 1 year ago

@microbit-carlos If MICROBIT_BLE_UTILITY_SERVICE, MICROBIT_BLE_UTILITY_SERVICE_PAIRING and MICROBIT_BLE_MAXIMUM_BONDS are intended to be configurable from codal.json and MakeCode, do they need to be added to yotta_cfg_mappings.h?

microbit-carlos commented 4 months ago

On Wednesday we tried bonding to the hex file posted in https://github.com/lancaster-university/codal-microbit-v2/issues/289#issuecomment-1671118562 and after the 9th bond the micro:bit cannot enter pairing mode anymore.

It animates the LEDs one by one and then when it's meant to show the Bluetooth logo nothing happens, the display just stays completely off. @martinwork any idea what could be happening or where it could be getting stuck?

martinwork commented 4 months ago

@microbit-carlos I wonder if there's a limit in https://github.com/microbit-foundation/codal-microbit-nrf5sdk