-
Notifications
You must be signed in to change notification settings - Fork 7.8k
Assignees
@Rob58329
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.