-
Notifications
You must be signed in to change notification settings - Fork 7.7k
Open
Labels
Status: Awaiting triageIssue is waiting for triageIssue is waiting for triage
Description
Board
ESP32 NodeMCU
Device Description
Board only
Hardware Configuration
Board only
Version
latest stable Release (if not listed below) ("github.com/espressif/arduino-esp32" as at 7Oct25)
Type
Task
IDE Name
Adruino IDE v1.8.19
Operating System
Window10
Flash frequency
80MHz
PSRAM enabled
no
Upload speed
115200
Description
On v3_3_1 "BLEDevice::deinit(false);" does NOT work properly, and after a following "BLEDevice::init()" you can't connect
to the "ESP32-BLE-SECURE" Server (eg. using the "nRF Connect" Android App).
[cf. before you do a "BLEDevice::deinit(false);" when you can connect reliably every time.]
(PS. On v3_3_0 [with slight modifications to "BLEDevice.cpp"] the CONFIG_BLUEDROID_ENABLED "BLEDevice::deinit(false);" command DOES appear to work correctly!)
Sketch
// On v3_3_1 "BLEDevice::deinit(false);" does NOT work properly, and after a following "BLEDevice::init()" you can't connect
// to the "ESP32-BLE-SECURE" Server (eg. using the "nRF Connect" Android App).
// [cf. before you do a "BLEDevice::deinit(false);" when you can connect reliably every time.]
// (PS. On v3_3_0 [with slight modifications to "BLEDevice.cpp"] the CONFIG_BLUEDROID_ENABLED "BLEDevice::deinit(false);" command DOES appear to work correctly!)
#define SERVER_PIN 123456
#define SERVER_NAME "ESP32-BLE-SECURE"
#if (ESP_ARDUINO_VERSION <= ESP_ARDUINO_VERSION_VAL(3, 3, 0))
#define USE_v3_3_0_SW
#endif
volatile boolean BLE_connect=0;
volatile boolean BLE_security=0;
boolean BLE_running=0;
int BLE_bonded=0;
#include "BLEDevice.h"
#include "BLEServer.h"
BLEServer *pServer=nullptr;
BLESecurity *pSecurity=nullptr;
void setup() {
Serial.begin(115200); delay(3000);
Serial.printf("ESP_ARDUINO=v%s\n",ESP_ARDUINO_VERSION_STR);
#ifdef USE_v3_3_0_SW
Serial.println("Using v3.3.0");
#else // v3.3.1
Serial.print("Using BLE stack: "); Serial.println(BLEDevice::getBLEStackString());
#endif
BLE_server_start(SERVER_NAME);
Serial.println("\nSerial Commands: d=Display Bonds, e=Erase All-Bonds, x=BLE_server_STOP, y=BLE_server_START");
}
uint32_t heap_old=0;
boolean security_old=false;
void loop() {
boolean security=BLE_security; if (security_old!=security) {security_old=security; Serial.printf("*** BLE_security=%s ***\n", security ? "On" : "Off");}
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)
if (c=='d') {Serial.print("->"); show_bonded_devices();}
if (c=='e') {Serial.print("->"); remove_all_bonded_devices();}
if (c=='x') {Serial.print("->"); BLE_server_stop();}
if (c=='y') {Serial.print("->"); BLE_server_start(SERVER_NAME);}
#elif defined(CONFIG_NIMBLE_ENABLED)
if (c=='d') {Serial.printf("->number_of_bonded_devices=%i\n", number_of_bonded_devices());}
if (c=='e') {Serial.print("->"); remove_all_bonded_devices();}
if (c=='x') {Serial.print("->"); BLE_server_stop();}
if (c=='y') {Serial.print("->"); BLE_server_start(SERVER_NAME);}
#endif
}
delay(100);
}
class MyServerCallbacks : public BLEServerCallbacks {
void onConnect(BLEServer *pServer) {BLE_connect=true; Serial.println("*BLE Device connected");}
#ifdef USE_v3_3_0_SW
void onDisconnect(BLEServer *pServer) {BLE_connect=false; BLE_security=false; pServer->startAdvertising(); Serial.println("*Device Disconnected");}
#else // v3.3.1
void onDisconnect(BLEServer *pServer) {BLE_connect=false; BLE_security=false; Serial.println("*Device Disconnected");}
#endif
};
BLEServerCallbacks *myServerCallbacks=nullptr;
void BLE_security_disconnect() {if (pServer) pServer->disconnect(pServer->getConnId()); BLE_security=false;}
class MySecurityCallbacks : public BLESecurityCallbacks {
uint32_t onPassKeyRequest() {Serial.println("BLE onPassKeyRequest"); return SERVER_PIN;}
void onPassKeyNotify(uint32_t pass_key) {Serial.printf("BLE Requested PassKey from Client=%u\n",pass_key);}
bool onConfirmPIN(uint32_t pass_key) {Serial.println("BLE onConfirmPIN"); vTaskDelay(5000); return true;}
bool onSecurityRequest() {Serial.println("BLE onSecurityRequest"); return true;}
#if defined(CONFIG_BLUEDROID_ENABLED)
void onAuthenticationComplete(esp_ble_auth_cmpl_t cmpl) {
BLE_security=(cmpl.success);
#elif defined(CONFIG_NIMBLE_ENABLED)
void onAuthenticationComplete(ble_gap_conn_desc *desc ) {
Serial.printf("authenticated=%i\n",desc->sec_state.authenticated); delay(1);
Serial.printf("bonded=%i\n",desc->sec_state.bonded); delay(1);
Serial.printf("authorize=%i\n",desc->sec_state.authorize); delay(1);
BLE_security=desc->sec_state.bonded;
#endif
Serial.printf("**Authentication %s\n", BLE_security ? "OK" : "FAIL"); delay(1);
if (BLE_security==0) BLE_security_disconnect();
}
};
MySecurityCallbacks *mySecurityCallbacks=nullptr;
void heap_display(int x=0) {
static uint32_t heap_old=0;
uint32_t heap_new=ESP.getFreeHeap();
Serial.printf("Heap%i=%u (diff=%i)\n",x,heap_new,heap_old-heap_new);
heap_old=heap_new;
}
void BLE_server_stop() {
if (BLE_running) {
Serial.println("BLE_server_stop");
BLE_bonded=number_of_bonded_devices();
BLE_running=false;
BLEDevice::stopAdvertising(); delay(50);
BLEDevice::deinit(false); delay(999);
if (pSecurity) {delete pSecurity; pSecurity=nullptr; Serial.println("del pSecurity");}
delay(50); heap_display(0);
} else Serial.println("BLE Already Stopped");
}
void BLE_server_start(const char* BLE_NAME) {
if (BLE_running) Serial.println("BLE Already Running");
else {
BLE_running=true;
Serial.println("BLE_server_start");
heap_display(1);
BLEDevice::init(BLE_NAME); delay(50);
pServer=BLEDevice::createServer(); // will only do anything if not already created!
if (myServerCallbacks==nullptr) {myServerCallbacks=new MyServerCallbacks(); Serial.println("new MyServerCallbacks()");}
pServer->setCallbacks(myServerCallbacks);
BLEAdvertising *pAdvertising = pServer->getAdvertising();
pAdvertising->setScanResponse(true); // default is already true
pAdvertising->setMinPreferred(0x06); // set to 0x06 to help with iPhone connections issue
pAdvertising->setMaxPreferred(0x40); // leave at 0x40 for Android connections
#ifndef USE_v3_3_0_SW
pServer->advertiseOnDisconnect(true);
#endif
if (mySecurityCallbacks==nullptr) {mySecurityCallbacks = new MySecurityCallbacks(); Serial.println("new MySecurityCallbacks()");}
BLEDevice::setSecurityCallbacks(mySecurityCallbacks);
if (pSecurity==nullptr) {pSecurity = new BLESecurity(); Serial.println("new BLESecurity()");}
Serial.printf("***** Server[%s] SERVER_PIN=%06u *****\n",BLE_NAME,SERVER_PIN);
#ifdef USE_v3_3_0_SW
pSecurity->setStaticPIN(SERVER_PIN);
pSecurity->setAuthenticationMode(ESP_LE_AUTH_REQ_SC_MITM_BOND);
pSecurity->setRespEncryptionKey(ESP_BLE_ENC_KEY_MASK | ESP_BLE_ID_KEY_MASK);
BLEDevice::setEncryptionLevel(ESP_BLE_SEC_ENCRYPT);
#else // v3.3.1
pSecurity->setPassKey(true, SERVER_PIN);
pSecurity->setAuthenticationMode(true, true, true);
BLESecurity::setEncryptionLevel(ESP_BLE_SEC_ENCRYPT);
#endif
pSecurity->setCapability(ESP_IO_CAP_OUT);
#ifdef CONFIG_BLUEDROID_ENABLED
uint8_t auth_option = ESP_BLE_ONLY_ACCEPT_SPECIFIED_AUTH_ENABLE; // Necessary: stops 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));
#endif
pAdvertising->start();
delay(50); heap_display(2);
}
}
#if defined(CONFIG_BLUEDROID_ENABLED)
inline int number_of_bonded_devices() {return esp_ble_get_bond_device_num();}
char bda_str[18];
inline 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("Bonded 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() {
int dev_num = esp_ble_get_bond_device_num();
if (dev_num<=0) {Serial.println("All bonds NOT deleted"); return;}
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);
Serial.println("All bonds deleted");
}
#elif defined(CONFIG_NIMBLE_ENABLED)
int number_of_bonded_devices() {
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));
if (rc) num_peers=-1; // error
} else Serial.println("Err: BLE not running");
return num_peers;
}
bool remove_all_bonded_devices() {
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);
}
#endif
Debug Message
ESP_ARDUINO=v3.3.1
Using BLE stack: Bluedroid
BLE_server_start
Heap1=229036 (diff=-229036)
new MyServerCallbacks()
new MySecurityCallbacks()
new BLESecurity()
***** Server[ESP32-BLE-SECURE] SERVER_PIN=123456 *****
Heap2=135920 (diff=93116)
Serial Commands: d=Display Bonds, e=Erase All-Bonds, x=BLE_server_STOP, y=BLE_server_START
*BLE Device connected
**Authentication OK
*** BLE_security=On ***
*Device Disconnected
*** BLE_security=Off ***
(ie. works ok before "BLEDevice::deinit(false);")
x->BLE_server_stop // do a "BLEDevice::deinit(false);"
del pSecurity
Heap0=227640 (diff=-91720)
y->BLE_server_start
Heap1=227640 (diff=0)
new BLESecurity()
***** Server[ESP32-BLE-SECURE] SERVER_PIN=123456 *****
Heap2=135892 (diff=91748)
(Now even though ""ESP32-BLE-SECURE" is advertising, you can't connect to it, and you don't get any Serial-Messages)
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.
Metadata
Metadata
Assignees
Labels
Status: Awaiting triageIssue is waiting for triageIssue is waiting for triage