-
Notifications
You must be signed in to change notification settings - Fork 7.7k
Description
Board
NodeMCU ESP32
Device Description
Plain module
Hardware Configuration
Plain module
Version
latest stable Release (if not listed below)
Type
Task
IDE Name
Arduino IDE v1.8.19 with https://github.com/espressif/arduino-esp32 at 5Sep25 (v3.3.0)
Operating System
Windows10
Flash frequency
80MHz
PSRAM enabled
no
Upload speed
115200
Description
There appears to be a new bug in the current "github.com/espressif/arduino-esp32 @5Sept25" Bluedroid-software (ESP32 orig) - (prossibly in BLESecurity.cpp): that after reboot it will only give you the prompt to enter a PIN the 1st time you try to connect, and if you fail to enter the correct PIN the 1st time, it will disconnect you, but subsequently will allow you to connect but NOT go through any securuty-authentication, and will NOT disconnect you.
Note that if you instead use "github.com/espressif/arduino-esp32 @19Jan25" (or infact just copy the "hardware\esp32\esp32\libraries\BLE\src" directory from 19Jan25 to the above 5Sept25 version), then the above bug does NOT happen (ie. it shows the correct behavior being that every time you connect after an incorrect-PIN you get the prompt to re-enter a correct-PIN, and it disconnects you if you dont get it right).
The below sketch demonstrates this - just try to connect using your mobile phone (eg. using the nRF-Connect App), but enter an incorrect PIN.
Sketch
// There appears to be a new bug in the current "github.com/espressif/arduino-esp32 @5Sept25" Bluedroid-software // (ESP32 orig) - (prossibly in BLESecurity.cpp): that after reboot it will only give you the prompt to enter a // PIN the 1st time you try to connect, and if you fail to enter the correct PIN the 1st time, it will disconnect // you, but subsequently will allow you to connect but NOT go through any securuty-authentication, and will NOT // disconnect you. // Note that if you instead use "github.com/espressif/arduino-esp32 @19Jan25" (or infact just copy the // "hardware\esp32\esp32\libraries\BLE\src" directory from 19Jan25 to the above 5Sept25 version), then // the above bug does NOT happen (ie. it shows the correct behavior being that every time you connect after // an incorrect-PIN you get the prompt to re-enter a correct-PIN, and it disconnects you if you dont get it right). // The below sketch demonstrates this - just try to connect using your mobile phone (eg. using the nRF-Connect App), // but enter an incorrect PIN. #if !defined(CONFIG_BLUEDROID_ENABLED) #error "This will only compile on Bluedroid based devices such as the ESP32 (ie. not the ESP32S3 etc)" #endif #define NEW_BLUEDROID_CODE ((ESP_ARDUINO_VERSION_MAJOR>=3) and (ESP_ARDUINO_VERSION_MINOR>=3)) // #define NEW_BLUEDROID_CODE false // use this if you copy the "BLE/src" directory from 19Jan25 to the above 5Sept25 version // NB. Ensure you re-start the Arduino-IDE after swapping the "BLE/src" directory to ensure it re-compiles everything. #include <BLEDevice.h> #include <BLEServer.h> BLEServer *pServer=nullptr; uint32_t BLE_PASSKEY=123456; // for BLE must be exactly 6 digits long! // once bonded passkey is n/a (can be changed without effecting bonded devices) volatile boolean BLE_connected=false; volatile boolean BLE_security=false; class MySecurityCallbacks : public BLESecurityCallbacks { bool onConfirmPIN(uint32_t pin) {Serial.printf("onConfirmPIN=%u\n",pin); return (pin==BLE_PASSKEY);} uint32_t onPassKeyRequest() {Serial.println("onPassKeyRequest"); return BLE_PASSKEY;} void onPassKeyNotify(uint32_t pass_key) {Serial.printf("onPassKeyNotify=%u\n", pass_key);} bool onSecurityRequest() {Serial.println("onSecurityRequest"); return true;} void onAuthenticationComplete(esp_ble_auth_cmpl_t cmpl) {Serial.printf("Auth %s\n",cmpl.success ? "OK" : "FAIL"); BLE_security=(cmpl.success);} }; class MyServerCallbacks : public BLEServerCallbacks { void onConnect(BLEServer *pServer) {BLE_connected=true; Serial.printf("Device connected (ID=%u)\n",pServer->getConnId());} void onDisconnect(BLEServer *pServer) {BLE_connected=false; BLE_security=false; pServer->startAdvertising();Serial.println("Device Disconnected");} }; void setup() { Serial.begin(115200); delay(2999); Serial.printf("ESP_ARDUINO=v%s\n",ESP_ARDUINO_VERSION_STR); // ESP_ARDUINO=v3.3.0 #if (NEW_BLUEDROID_CODE) Serial.println("Running on the new NEW_BLUEDROID_CODE (BLE/src)"); Serial.print("Using BLE stack: "); Serial.println(BLEDevice::getBLEStackString()); // Using BLE stack: Bluedroid #else Serial.println("Running on the older BLUEDROID_CODE (BLE/src)"); #endif Serial.println("BLEDevice::init..."); BLEDevice::init("Secure BLE Client"); BLEDevice::setSecurityCallbacks(new MySecurityCallbacks()); pServer = BLEDevice::createServer(); pServer->setCallbacks(new MyServerCallbacks()); BLEAdvertising *pAdvertising = pServer->getAdvertising(); pAdvertising->start(); BLESecurity *pSecurity = new BLESecurity(); pSecurity->setCapability(ESP_IO_CAP_OUT); // Not sure if this is necessary? #if (NEW_BLUEDROID_CODE) pSecurity->setPassKey(true,BLE_PASSKEY); pSecurity->setAuthenticationMode(true,false,false); BLESecurity::setEncryptionLevel(ESP_BLE_SEC_ENCRYPT); // Not sure if this is necessary? #else esp_ble_gap_set_security_param(ESP_BLE_SM_SET_STATIC_PASSKEY, &BLE_PASSKEY, sizeof(uint32_t)); BLEDevice::setEncryptionLevel(ESP_BLE_SEC_ENCRYPT); // Necessary #endif uint8_t auth_option = ESP_BLE_ONLY_ACCEPT_SPECIFIED_AUTH_ENABLE; // essential to stop Clients with No-PIN connecting/authorising esp_ble_gap_set_security_param(ESP_BLE_SM_ONLY_ACCEPT_SPECIFIED_SEC_AUTH, &auth_option, sizeof(uint8_t)); pSecurity->setAuthenticationMode(ESP_LE_AUTH_REQ_SC_MITM_BOND); // override the "pSecurity->setAuthenticationMode(true,0,0);" // Not sure if this is necessary? pSecurity->setInitEncryptionKey(ESP_BLE_ENC_KEY_MASK | ESP_BLE_ID_KEY_MASK); // Not sure if this is necessary? pSecurity->setRespEncryptionKey(ESP_BLE_ENC_KEY_MASK | ESP_BLE_ID_KEY_MASK); // Not sure if this is necessary? Serial.println("BLE Started. You can now connect from your phone (eg. using nRF-Connect)"); Serial.println("Serial Commands: d=Display Bonds, e=Erase All-Bonds"); } void loop() { boolean secure=BLE_security; static boolean secure_old=false; if (secure_old!=secure) {secure_old=secure; Serial.printf("**Secure Connection=%s\n", secure ? "On" : "Off");} while (Serial.available()) { char c=Serial.read(); if (c>=32) Serial.write(c); else Serial.println(); if (c=='d') show_bonded_devices(); if (c=='e') remove_all_bonded_devices(); } delay(100); } char bda_str[18]; char *bda2str(const uint8_t *bda) { sprintf(bda_str, "%02x:%02x:%02x:%02x:%02x:%02x", bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]); return bda_str; } void show_bonded_devices() { int dev_num = esp_ble_get_bond_device_num(); esp_ble_bond_dev_t *dev_list = (esp_ble_bond_dev_t *)malloc(sizeof(esp_ble_bond_dev_t) * dev_num); esp_ble_get_bond_device_list(&dev_num, dev_list); Serial.printf("\nBonded devices number: %d\n", dev_num); for (int i = 0; i < dev_num; i++) {Serial.printf("Found bonded device #%d = %s\n", i+1, bda2str(dev_list[i].bd_addr));} free(dev_list); } void remove_all_bonded_devices() { Serial.println("\nRemoving all bonded devices"); int dev_num = esp_ble_get_bond_device_num(); esp_ble_bond_dev_t *dev_list = (esp_ble_bond_dev_t *)malloc(sizeof(esp_ble_bond_dev_t) * dev_num); esp_ble_get_bond_device_list(&dev_num, dev_list); for (int i = 0; i < dev_num; i++) esp_ble_remove_bond_device(dev_list[i].bd_addr); free(dev_list); }
Debug Message
ESP_ARDUINO=v3.3.0
Running on the new NEW_BLUEDROID_CODE (BLE/src)
Using BLE stack: Bluedroid
BLEDevice::init...
BLESecurity: Initializing
setPassKey: staticPasskey=1, passkey=123456
BLE Started. You can now connect from your phone (eg. using nRF-Connect)
Serial Commands: d=Display Bonds, e=Erase All-Bonds
// 1st connect with incorrect PIN
Device connected (ID=0)
onPassKeyNotify=123456
Auth FAIL
Device Disconnected
// 2nd connect
Device connected (ID=0)
// ... server never disconnects client...
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.