esp-nimble-cpp icon indicating copy to clipboard operation
esp-nimble-cpp copied to clipboard

whitelisted connections do not persist across power cycles

Open cmorganBE opened this issue 1 year ago • 4 comments

Using https://github.com/cmorganBE/esp-nimble-cpp-test/tree/bonding_with_whitelist_control_and_sc (latest esp-nimble-cpp), esp-idf v5.2.2

BT_NIMBLE_NVS_PERSIST is y

Program with:

idf.py build erase-flash flash monitor

Steps to reproduce:

  1. Connect with lightblue iOS during 'Any'
  2. Disconnect lightblue and confirm it can connect during 'Whitelist only' mode
  3. Power cycle esp32s3-devkit-c1
  4. Lightblue unable to connect during 'Whitelist only' mode.

@h2zero I thought this was working before but maybe I forgot or didn't test it? Same arrangement as before works in terms of hourly, if that helps expedite looking into this.

cmorganBE avatar Jul 02 '24 19:07 cmorganBE

@cmorganBE The whitelist is not persisted in NVS by the stack as far as I know. You would need to populate it on startup with your own persisted list or just get all the addresses of the bonded devices.

h2zero avatar Jul 02 '24 21:07 h2zero

So the bonding is persisted, as indicated by the menuconfig option but not whitelists? Weird….

Get Outlook for iOShttps://aka.ms/o0ukef


From: h2zero @.> Sent: Tuesday, July 2, 2024 5:05:13 PM To: h2zero/esp-nimble-cpp @.> Cc: Morgan, Chris @.>; Mention @.> Subject: Re: [h2zero/esp-nimble-cpp] whitelisted connections do not persist across power cycles (Issue #174)

@cmorganBEhttps://github.com/cmorganBE The whitelist is not persisted in NVS by the stack as far as I know. You would need to populate it on startup with your own persisted list or just get all the addresses of the bonded devices.

— Reply to this email directly, view it on GitHubhttps://github.com/h2zero/esp-nimble-cpp/issues/174#issuecomment-2204417491, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AMMP74HQCGQF237MI5XRPJTZKMIYTAVCNFSM6AAAAABKIGO6RGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDEMBUGQYTONBZGE. You are receiving this because you were mentioned.Message ID: @.***>

CAUTION: This email originated from outside the organization. Do not click links or open attachments you were not expecting.

cmorganBE avatar Jul 02 '24 21:07 cmorganBE

Yes, that's how I perceive it, I think it's because whitelists change more frequently.

h2zero avatar Jul 02 '24 21:07 h2zero

Ahh k. I can’t find any info on it being persisted so I think it isn’t. I’ll implement persisting it here and see how it goes.

Get Outlook for iOShttps://aka.ms/o0ukef


From: h2zero @.> Sent: Tuesday, July 2, 2024 5:22:10 PM To: h2zero/esp-nimble-cpp @.> Cc: Morgan, Chris @.>; Mention @.> Subject: Re: [h2zero/esp-nimble-cpp] whitelisted connections do not persist across power cycles (Issue #174)

Yes, that's how I perceive it, I think it's because whitelists change more frequently.

— Reply to this email directly, view it on GitHubhttps://github.com/h2zero/esp-nimble-cpp/issues/174#issuecomment-2204462883, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AMMP74GOLJJUYK2746KPPCDZKMKYFAVCNFSM6AAAAABKIGO6RGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDEMBUGQ3DEOBYGM. You are receiving this because you were mentioned.Message ID: @.***>

CAUTION: This email originated from outside the organization. Do not click links or open attachments you were not expecting.

cmorganBE avatar Jul 02 '24 22:07 cmorganBE

@h2zero for serializing and deserializing the whitelist addresses, I presume the NimBLEAddress type has to be preserved and restored as well? I'm going to start down that path, assuming its necessary, until I hear otherwise.

cmorganBE avatar Jul 08 '24 17:07 cmorganBE

Yes the address type is necessary. I would just store the NimBLEAddress used as a blob and read it back on restart.

h2zero avatar Jul 08 '24 19:07 h2zero

@h2zero I thought of going that route but how to avoid having too many whitelisted devices? Not that anyone might pair that many but thought it made sense to have some upper limit. And then if there is a limit, how to ensure the new ones replace the old ones? I was going to store an array of N entries in a blob but yeah NimBLEAddress may be POD and safe to persist...

cmorganBE avatar Jul 08 '24 19:07 cmorganBE

The whitelist has a limit of 12 I believe. I would erase whitelist entries by comparing with the bonded device list and delete any addresses that are no longer bonded.

h2zero avatar Jul 08 '24 19:07 h2zero

@h2zero is the assumption that there is a limit to bonded devices as well? If so that approach should work. Store in a single blob or separate nvs entries (then they have to have unique names which could be the address but that seems wasteful...)

cmorganBE avatar Jul 08 '24 19:07 cmorganBE

Yes there is a bond limit, defaults to 3, you can change it in the config.

h2zero avatar Jul 08 '24 19:07 h2zero

@h2zero safe to assume the whitelist addresses == bonded addresses?

cmorganBE avatar Jul 08 '24 19:07 cmorganBE

I use bonded addresses as my whitelist addresses and it works as intended. No additional data needs to be stored.

finger563 avatar Jul 08 '24 19:07 finger563

@finger563 doh, that's an even better idea.... wow thank you for that

cmorganBE avatar Jul 08 '24 19:07 cmorganBE

@finger563 and that works since the bonding stores the address type? I'm unsure of how the type is used so it wasn't clear that the bonded address would know its type like the whitelist might require.

cmorganBE avatar Jul 08 '24 19:07 cmorganBE

No address type is required, I just load the bonded address and create a NimBLE address from it and pass that to the whitelist

finger563 avatar Jul 08 '24 20:07 finger563

let me whip that up and give it a shot

cmorganBE avatar Jul 08 '24 20:07 cmorganBE

            auto paired_addresses = ble_gatt_server_.get_paired_devices();
            for (const auto &address : paired_addresses) {
                logger_.info("Adding {} to whitelist", address.toString());
                NimBLEDevice::whiteListAdd(address);
            }
            // you of course do have to set `scan_request_whitelist` and `connect_whitelist` to true in the `setScanFilter(...)`

Where my server implements this:

  /// Get the paired devices
  /// @return The paired devices as a vector of Addresses.
  std::vector<NimBLEAddress> get_paired_devices() {
    std::vector<NimBLEAddress> paired_devices;
    auto num_bonds = NimBLEDevice::getNumBonds();
    for (int i = 0; i < num_bonds; i++) {
      auto bond_addr = NimBLEDevice::getBondedAddress(i);
      paired_devices.push_back(bond_addr);
    }
    return paired_devices;
  }

finger563 avatar Jul 08 '24 20:07 finger563

That's very similar to what I have here:

        for(int i = 0; i < NimBLEDevice::getNumBonds(); i++)
        {
            auto address = NimBLEDevice::getBondedAddress(i);
            NimBLEDevice::whiteListAdd(address);
        }

cmorganBE avatar Jul 08 '24 20:07 cmorganBE

yep, that appears to be working well here, thank you much @finger563

cmorganBE avatar Jul 08 '24 20:07 cmorganBE

Yes, that is by far the best way to go about this.

h2zero avatar Jul 09 '24 04:07 h2zero

Closing as fixed!

cmorganBE avatar Jul 10 '24 21:07 cmorganBE