NimBLE-Arduino icon indicating copy to clipboard operation
NimBLE-Arduino copied to clipboard

Bonding must always be re-established after NimBLEDevice::deinit(false).

Open RunpoThomas opened this issue 1 year ago • 6 comments

Hello, I am currently trying to equip a battery-powered device with NimBLE to send sensor data to a smartphone.

Hardware used: ESP32-S3 Programming environment: Arduino IDE 2.3.2 Library: NimBLE-Arduino 1.4.2

To save battery I use the command “NimBLEDevice::deinit(false)” after advertising when no device is connected to the server. I want to bond the server with the smartphone once and then a connection should always be possible.

Implementation of the secure connection:

class MyServerCallbacks : public NimBLEServerCallbacks {

  void onConnect(NimBLEServer* pServer, ble_gap_conn_desc* desc) {
    NimBLEDevice::setSecurityAuth(true,true,true);
    NimBLEDevice::setSecurityIOCap	(0x00);
    NimBLEDevice::setSecurityInitKey	(BLE_SM_PAIR_KEY_DIST_ENC |  BLE_SM_PAIR_KEY_DIST_ID);
    NimBLEDevice::setSecurityRespKey(BLE_SM_PAIR_KEY_DIST_ENC |  BLE_SM_PAIR_KEY_DIST_ID);	
    _pin = esp_random() % 900000 + 100000;
    NimBLEDevice::setSecurityPasskey(_pin);
    Serial.println(_pin);
    NimBLEDevice::startSecurity	(desc-> conn_handle);
    
    deviceConnected = true;
    NimBLEAdvertising *pAdvertising = NimBLEDevice::getAdvertising();
    pAdvertising->stop();
  }

  void onDisconnect(NimBLEServer *pServer, ble_gap_conn_desc *desc) {
    deviceConnected = false;
  }
};

Error message: E (231388) NimBLE: failed to configure restored IRK

The passkey must be entered again for each connection. I have not found any information about this problem. This problem does not occur without the deinit() function. I would be very grateful for help.

RunpoThomas avatar Sep 12 '24 06:09 RunpoThomas

Please try setting the security config after init instead of in the callback.

NimBLEDevice::init();
NimBLEDevice::setSecurityAuth(true,true,true);
NimBLEDevice::setSecurityIOCap	(0x00);
NimBLEDevice::setSecurityInitKey	(BLE_SM_PAIR_KEY_DIST_ENC |  BLE_SM_PAIR_KEY_DIST_ID);
NimBLEDevice::setSecurityRespKey(BLE_SM_PAIR_KEY_DIST_ENC |  BLE_SM_PAIR_KEY_DIST_ID);

h2zero avatar Sep 15 '24 15:09 h2zero

Hello, thank you very much for your response. Unfortunately, the same effect also occurs in this case. If the corresponding characteristics are accessed, the passkey must be re-entered each time a new connection is established (only when using deinit()).

RunpoThomas avatar Sep 16 '24 07:09 RunpoThomas

Now I get this error message: E NimBLEDevice: esp_nimble_hci_and_controller_deinit() failed with error: 259

RunpoThomas avatar Sep 16 '24 08:09 RunpoThomas

That error is from here: https://github.com/espressif/esp-idf/blob/c01512f4b0a5086b577f1c8d00378c3e4ae6ee33/components/bt/controller/esp32/bt.c#L1811

Looks like the controller wasn't initialized when you called deint.

h2zero avatar Sep 21 '24 16:09 h2zero

I'll have a look at that. Thanks for the answer.

RunpoThomas avatar Sep 24 '24 06:09 RunpoThomas

I'm interested in any updates, facing the same problem with a hid device connecting to an android smartwatch. Notably Linux, Mac, and Windows platforms have had no issues reconnecting (retaining bonding) after deinit and init. Furthermore, restarting the ESP32-s3 instead of directly doing the initialization works...

VisaJE avatar Apr 02 '25 13:04 VisaJE