-
Notifications
You must be signed in to change notification settings - Fork 7.7k
Description
Board
ESP32C3 or ESP32S3
Device Description
Board only
Hardware Configuration
Board only
Version
latest stable Release (if not listed below)
Type
Bug
IDE Name
Arduino IDE v1.8.19 with github.com/espressif/arduino-esp32 as at 14Sep25
Operating System
Windows 10
Flash frequency
80MHz
PSRAM enabled
no
Upload speed
115200
Description
The Nimble BLE_Paired_Device_Info NOT stored in NVS, and forgotton after every reboot.
This failure to save occurrs on both the ESP32C3 and ESP32S3, so probably on all ESP32-NimBLE devices
The below sketch allows this issue to be tested.
Test-A: pair-your-phone to the ESP32C3/ESP32S3, check its paired by pressing 'd'. Then reboot the ESP32S3, and press 'd' again (or try to re-connect your phone).
Test-B: pair-your-phone to the ESP32C3/ESP32S3, check its paired by pressing 'd'. Then delete NVS by pressing 'z'. Then check 'd' again. (or dis/re-connect your phone)
Sketch
// BLE NimBLE: The Nimble BLE_Paired_Device_Info NOT stored in NVS, and forgotton after every reboot.
// This failure to save occurrs on both the ESP32C3 and ESP32S3, so probably on all ESP32-NimBLE devices
// Test-A: pair-your-phone to the ESP32C3/ESP32S3, check its paired by pressing 'd'. Then reboot the ESP32S3, and press 'd' again (or try to re-connect your phone).
// Test-B: pair-your-phone to the ESP32C3/ESP32S3, check its paired by pressing 'd'. Then delete NVS by pressing 'z'. Then check 'd' again. (or dis/re-connect your phone)
#if !defined(CONFIG_NIMBLE_ENABLED)
#error "This code only works using NimBLE"
#endif
#define BLE_NAME "Secure BLE Server"
#define SERVER_PIN 123456
boolean BLE_running=0;
#include "BLEDevice.h"
#include "BLEServer.h"
BLEServer *pServer=nullptr;
class MyServerCallbacks : public BLEServerCallbacks {
void onConnect(BLEServer *pServer) {Serial.printf("Device connected (ID=%u)\n",pServer->getConnId()); delay(2);}
void onDisconnect(BLEServer *pServer) {Serial.println("Device Disconnected"); delay(2);}
};
class MySecurityCallbacks : public BLESecurityCallbacks {
void onPassKeyNotify(uint32_t pass_key) {Serial.println("Requested PassKey from Client");}
void onAuthenticationComplete(ble_gap_conn_desc *desc ) {
boolean BLE_security=desc->sec_state.bonded;
Serial.printf("&&&&& Authentication %s &&&&&\n", BLE_security ? "OK" : "FAIL"); delay(2);
if((!BLE_security) and (pServer)) pServer->disconnect(pServer->getConnId());
}
};
void setup() {
Serial.begin(115200); delay(2999);
Serial.printf("ESP_ARDUINO=v%s+\n",ESP_ARDUINO_VERSION_STR); // ESP_ARDUINO=v3.3.0+
Serial.print("Using BLE stack: "); Serial.println(BLEDevice::getBLEStackString());
BLE_server_start(BLE_NAME);
Serial.printf("Now you can Connect from your phone (pw=%u)\n",SERVER_PIN);
Serial.println("[Serial Commands: d=Display Bonds, e=Erase All-Bonds, z=reset_NVS]");
}
void loop() {
while (Serial.available()) {
char c=Serial.read();
if (c>=32) Serial.write(c);
else if (c==10) {}
else Serial.println();
#if defined(CONFIG_BLUEDROID_ENABLED)
#error "Use Nimble fot this issue"
#else
if (c=='d') {Serial.print("->"); Serial.printf("getNumBonds=%i\n", getNumBonds());}
if (c=='e') {Serial.println("->deleteAllBonds"); deleteAllBonds();}
if (c=='z') {Serial.print("->"); reset_NVS();}
#endif
}
delay(100);
}
uint32_t BLE_passkey=SERVER_PIN;
void BLE_server_start(const char* BLE_name) {
if (BLE_running) Serial.println("Already Running");
else {
BLE_running=true;
Serial.println("Starting BLE");
BLEDevice::init(BLE_name); delay(50);
MySecurityCallbacks *mySecurityCallbacks = new MySecurityCallbacks();
BLEDevice::setSecurityCallbacks(mySecurityCallbacks);
BLESecurity *pSecurity = new BLESecurity();
pSecurity->setCapability(ESP_IO_CAP_OUT);
pSecurity->setPassKey(true, BLE_passkey);
pSecurity->setAuthenticationMode(true, true, true);
pServer = BLEDevice::createServer();
pServer->advertiseOnDisconnect(true);
BLEServerCallbacks *myServCallbacks=new MyServerCallbacks();
pServer->setCallbacks(myServCallbacks);
BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
pAdvertising->setScanResponse(true);
pAdvertising->setMinPreferred(0x06); // functions that help with iPhone connections issue
pAdvertising->setMaxPreferred(0x12);
BLEDevice::startAdvertising();
}
}
#include <nvs_flash.h>
void reset_NVS() {
Serial.println("Clearing NVS pairing data (but does NOT currently clear THESE bonds)...");
nvs_flash_erase();
nvs_flash_init();
}
int getNumBonds() {
int num_peers=-1;
if (BLE_running) {
ble_addr_t peer_id_addrs[MYNEWT_VAL(BLE_STORE_MAX_BONDS)];
int rc = ble_store_util_bonded_peers(&peer_id_addrs[0], &num_peers, MYNEWT_VAL(BLE_STORE_MAX_BONDS)); // NOT using ble_store_util_peer_set!
if (rc) num_peers=-1; // an error has occured
} else Serial.println("Err: BLE not running");
return num_peers;
}
bool deleteAllBonds() {
int rc=-1;
if (BLE_running) {
int rc = ble_store_clear();
if (rc) Serial.printf("Failed to delete all bonds: rc=%i\n", rc);
else Serial.println("All bonds deleted");
} else Serial.println("Err: BLE not running");
return (!rc);
}
Debug Message
ESP_ARDUINO=v3.3.0+
Using BLE stack: NimBLE
Starting BLE
Now you can Connect from your phone (pw=123456)
[Serial Commands: d=Display Bonds, e=Erase All-Bonds, z=reset_NVS]
Device connected (ID=1)
Requested PassKey from Client
&&&&& Authentication OK &&&&&
d->getNumBonds=1
z->Clearing NVS pairing data (but does NOT currently clear THESE bonds)...
d->getNumBonds=1
// Rebooted Board Here
ESP_ARDUINO=v3.3.0+
Using BLE stack: NimBLE
Starting BLE
Now you can Connect from your phone (pw=123456)
[Serial Commands: d=Display Bonds, e=Erase All-Bonds, z=reset_NVS]
d->getNumBonds=0
Other Steps to Reproduce
No response
I have checked existing issues, online documentation and the Troubleshooting Guide
- I confirm I have checked existing issues, online documentation and Troubleshooting guide.