From bf8cfac94f22f8fbfde9ef59741de61588358e74 Mon Sep 17 00:00:00 2001
From: Tomas Pilny <tomas.pilny@espressif.com>
Date: Tue, 18 Jul 2023 10:24:11 +0200
Subject: [PATCH 01/14] Renamed SerialToSerialBT_SSP_pairing

---
 .../.skip.esp32c3                             |  0
 .../.skip.esp32c6                             |  0
 .../.skip.esp32h2                             |  0
 .../.skip.esp32s2                             |  0
 .../.skip.esp32s3                             |  0
 .../SerialToSerialBT_SSP.ino}                 | 19 ++++++++++++-------
 6 files changed, 12 insertions(+), 7 deletions(-)
 rename libraries/BluetoothSerial/examples/{SerialToSerialBT_SSP_pairing => SerialToSerialBT_SSP}/.skip.esp32c3 (100%)
 rename libraries/BluetoothSerial/examples/{SerialToSerialBT_SSP_pairing => SerialToSerialBT_SSP}/.skip.esp32c6 (100%)
 rename libraries/BluetoothSerial/examples/{SerialToSerialBT_SSP_pairing => SerialToSerialBT_SSP}/.skip.esp32h2 (100%)
 rename libraries/BluetoothSerial/examples/{SerialToSerialBT_SSP_pairing => SerialToSerialBT_SSP}/.skip.esp32s2 (100%)
 rename libraries/BluetoothSerial/examples/{SerialToSerialBT_SSP_pairing => SerialToSerialBT_SSP}/.skip.esp32s3 (100%)
 rename libraries/BluetoothSerial/examples/{SerialToSerialBT_SSP_pairing/SerialToSerialBT_SSP_pairing.ino => SerialToSerialBT_SSP/SerialToSerialBT_SSP.ino} (62%)

diff --git a/libraries/BluetoothSerial/examples/SerialToSerialBT_SSP_pairing/.skip.esp32c3 b/libraries/BluetoothSerial/examples/SerialToSerialBT_SSP/.skip.esp32c3
similarity index 100%
rename from libraries/BluetoothSerial/examples/SerialToSerialBT_SSP_pairing/.skip.esp32c3
rename to libraries/BluetoothSerial/examples/SerialToSerialBT_SSP/.skip.esp32c3
diff --git a/libraries/BluetoothSerial/examples/SerialToSerialBT_SSP_pairing/.skip.esp32c6 b/libraries/BluetoothSerial/examples/SerialToSerialBT_SSP/.skip.esp32c6
similarity index 100%
rename from libraries/BluetoothSerial/examples/SerialToSerialBT_SSP_pairing/.skip.esp32c6
rename to libraries/BluetoothSerial/examples/SerialToSerialBT_SSP/.skip.esp32c6
diff --git a/libraries/BluetoothSerial/examples/SerialToSerialBT_SSP_pairing/.skip.esp32h2 b/libraries/BluetoothSerial/examples/SerialToSerialBT_SSP/.skip.esp32h2
similarity index 100%
rename from libraries/BluetoothSerial/examples/SerialToSerialBT_SSP_pairing/.skip.esp32h2
rename to libraries/BluetoothSerial/examples/SerialToSerialBT_SSP/.skip.esp32h2
diff --git a/libraries/BluetoothSerial/examples/SerialToSerialBT_SSP_pairing/.skip.esp32s2 b/libraries/BluetoothSerial/examples/SerialToSerialBT_SSP/.skip.esp32s2
similarity index 100%
rename from libraries/BluetoothSerial/examples/SerialToSerialBT_SSP_pairing/.skip.esp32s2
rename to libraries/BluetoothSerial/examples/SerialToSerialBT_SSP/.skip.esp32s2
diff --git a/libraries/BluetoothSerial/examples/SerialToSerialBT_SSP_pairing/.skip.esp32s3 b/libraries/BluetoothSerial/examples/SerialToSerialBT_SSP/.skip.esp32s3
similarity index 100%
rename from libraries/BluetoothSerial/examples/SerialToSerialBT_SSP_pairing/.skip.esp32s3
rename to libraries/BluetoothSerial/examples/SerialToSerialBT_SSP/.skip.esp32s3
diff --git a/libraries/BluetoothSerial/examples/SerialToSerialBT_SSP_pairing/SerialToSerialBT_SSP_pairing.ino b/libraries/BluetoothSerial/examples/SerialToSerialBT_SSP/SerialToSerialBT_SSP.ino
similarity index 62%
rename from libraries/BluetoothSerial/examples/SerialToSerialBT_SSP_pairing/SerialToSerialBT_SSP_pairing.ino
rename to libraries/BluetoothSerial/examples/SerialToSerialBT_SSP/SerialToSerialBT_SSP.ino
index c440545fcf3..1bbabdbb27a 100644
--- a/libraries/BluetoothSerial/examples/SerialToSerialBT_SSP_pairing/SerialToSerialBT_SSP_pairing.ino
+++ b/libraries/BluetoothSerial/examples/SerialToSerialBT_SSP/SerialToSerialBT_SSP.ino
@@ -1,8 +1,11 @@
-//This example code is in the Public Domain (or CC0 licensed, at your option.)
-//By Richard Li - 2020
+// This example code is in the Public Domain (or CC0 licensed, at your option.)
+// By Richard Li - 2020
 //
-//This example creates a bridge between Serial and Classical Bluetooth (SPP with authentication)
-//and also demonstrate that SerialBT have the same functionalities of a normal Serial
+// This example creates a bridge between Serial and Classical Bluetooth (SPP with authentication)
+// and also demonstrate that SerialBT have the same functionalities of a normal Serial
+// SSP - Simple Secure Pairing - The device (ESP32) will display random number and the user is responsible of comparing it to the number
+// displayed on the other device (for example phone).
+// If the numbers match the user authenticates the pairing.
 
 #include "BluetoothSerial.h"
 
@@ -14,13 +17,15 @@
 #error Serial Bluetooth not available or not enabled. It is only available for the ESP32 chip.
 #endif
 
+const char * deviceName = "ESP32_SSP_example";
+
 BluetoothSerial SerialBT;
 boolean confirmRequestPending = true;
 
 void BTConfirmRequestCallback(uint32_t numVal)
 {
   confirmRequestPending = true;
-  Serial.println(numVal);
+  Serial.printf("The PIN is: %lu\n", numVal);
 }
 
 void BTAuthCompleteCallback(boolean success)
@@ -43,8 +48,8 @@ void setup()
   SerialBT.enableSSP();
   SerialBT.onConfirmRequest(BTConfirmRequestCallback);
   SerialBT.onAuthComplete(BTAuthCompleteCallback);
-  SerialBT.begin("ESP32test"); //Bluetooth device name
-  Serial.println("The device started, now you can pair it with bluetooth!");
+  SerialBT.begin(deviceName); //Bluetooth device name
+  Serial.printf("The device started with name \"%s\", now you can pair it with Bluetooth!\n", deviceName);
 }
 
 void loop()

From c1c3e2b8785365a723f7b8247b63ccf640feb49b Mon Sep 17 00:00:00 2001
From: Tomas Pilny <tomas.pilny@espressif.com>
Date: Mon, 24 Jul 2023 13:26:53 +0200
Subject: [PATCH 02/14] Clarified useage of SPP example

---
 .../SerialToSerialBT_SSP.ino                  | 54 ++++++++++++++-----
 1 file changed, 40 insertions(+), 14 deletions(-)

diff --git a/libraries/BluetoothSerial/examples/SerialToSerialBT_SSP/SerialToSerialBT_SSP.ino b/libraries/BluetoothSerial/examples/SerialToSerialBT_SSP/SerialToSerialBT_SSP.ino
index 1bbabdbb27a..8934fae3ee1 100644
--- a/libraries/BluetoothSerial/examples/SerialToSerialBT_SSP/SerialToSerialBT_SSP.ino
+++ b/libraries/BluetoothSerial/examples/SerialToSerialBT_SSP/SerialToSerialBT_SSP.ino
@@ -5,16 +5,26 @@
 // and also demonstrate that SerialBT have the same functionalities of a normal Serial
 // SSP - Simple Secure Pairing - The device (ESP32) will display random number and the user is responsible of comparing it to the number
 // displayed on the other device (for example phone).
-// If the numbers match the user authenticates the pairing.
+// If the numbers match the user authenticates the pairing on both devices - on phone simply press "Pair" and in terminal for the sketch send 'Y' or 'y' to confirm.
+// Alternatively uncomment AUTO_PAIR to skip the terminal confirmation.
 
 #include "BluetoothSerial.h"
 
+//#define AUTO_PAIR // Uncomment to skip the terminal confirmation.
+
+// Check if BlueTooth is available
 #if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
-#error Bluetooth is not enabled! Please run `make menuconfig` to and enable it
+  #error Bluetooth is not enabled! Please run `make menuconfig` to and enable it
 #endif
 
+// Check Serial Port Profile
 #if !defined(CONFIG_BT_SPP_ENABLED)
-#error Serial Bluetooth not available or not enabled. It is only available for the ESP32 chip.
+  #error Serial Port Profile for BlueTooth is not available or not enabled. It is only available for the ESP32 chip.
+#endif
+
+// Check Simple Secure Pairing
+#if !defined(CONFIG_BT_SSP_ENABLED)
+  #error Simple Secure Pairing for BlueTooth is not available or not enabled.
 #endif
 
 const char * deviceName = "ESP32_SSP_example";
@@ -25,7 +35,11 @@ boolean confirmRequestPending = true;
 void BTConfirmRequestCallback(uint32_t numVal)
 {
   confirmRequestPending = true;
-  Serial.printf("The PIN is: %lu\n", numVal);
+#ifndef AUTO_PAIR
+  Serial.printf("The PIN is: %lu. If it matches number displayed on the other device write \'Y\' or \'y\':\n", numVal);
+#else
+  SerialBT.confirmReply(true);
+#endif
 }
 
 void BTAuthCompleteCallback(boolean success)
@@ -41,19 +55,36 @@ void BTAuthCompleteCallback(boolean success)
   }
 }
 
+void serial_response(){
+  if (Serial.available())
+    {
+      SerialBT.write(Serial.read());
+    }
+    if (SerialBT.available())
+    {
+      Serial.write(SerialBT.read());
+    }
+    delay(20);
+}
 
 void setup()
 {
   Serial.begin(115200);
   SerialBT.enableSSP();
+  SerialBT.dropCache();
   SerialBT.onConfirmRequest(BTConfirmRequestCallback);
   SerialBT.onAuthComplete(BTAuthCompleteCallback);
   SerialBT.begin(deviceName); //Bluetooth device name
-  Serial.printf("The device started with name \"%s\", now you can pair it with Bluetooth!\n", deviceName);
+#ifndef AUTO_PAIR
+  Serial.printf("The device started with name \"%s\", now you can pair it with Bluetooth!\nIf the numbers in terminal and on the other device match, press \"Pair\" in phone/computer and write \'Y\' or \'y\' in terminal\n", deviceName);
+#else
+  Serial.printf("The device started with name \"%s\", now you can pair it with Bluetooth!\nIf the numbers in terminal and on the other device match, press \"Pair\" in phone/computer.\n", deviceName);
+#endif
 }
 
 void loop()
 {
+#ifndef AUTO_PAIR
   if (confirmRequestPending)
   {
     if (Serial.available())
@@ -71,14 +102,9 @@ void loop()
   }
   else
   {
-    if (Serial.available())
-    {
-      SerialBT.write(Serial.read());
-    }
-    if (SerialBT.available())
-    {
-      Serial.write(SerialBT.read());
-    }
-    delay(20);
+    serial_response();
   }
+#else
+  serial_response();
+#endif
 }

From cec60c08041dd88089c5924c2f1ecdbd5b4c6665 Mon Sep 17 00:00:00 2001
From: Tomas Pilny <tomas.pilny@espressif.com>
Date: Mon, 24 Jul 2023 13:31:55 +0200
Subject: [PATCH 03/14] Added missing events

---
 .../BluetoothSerial/src/BluetoothSerial.cpp   | 31 +++++++++++++++++--
 1 file changed, 28 insertions(+), 3 deletions(-)

diff --git a/libraries/BluetoothSerial/src/BluetoothSerial.cpp b/libraries/BluetoothSerial/src/BluetoothSerial.cpp
index 52254437923..8f54de66a27 100644
--- a/libraries/BluetoothSerial/src/BluetoothSerial.cpp
+++ b/libraries/BluetoothSerial/src/BluetoothSerial.cpp
@@ -24,7 +24,7 @@
 #if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BLUEDROID_ENABLED)
 
 #ifdef ARDUINO_ARCH_ESP32
-#include "esp32-hal-log.h"
+  #include "esp32-hal-log.h"
 #endif
 
 #include "BluetoothSerial.h"
@@ -567,10 +567,18 @@ static void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *pa
             log_i("ESP_BT_GAP_KEY_REQ_EVT Please enter passkey!");
             break;
 
+        case ESP_BT_GAP_READ_RSSI_DELTA_EVT:
+            log_i("ESP_BT_GAP_READ_RSSI_DELTA_EVT Read rssi event");
+            break;
+
         case ESP_BT_GAP_CONFIG_EIR_DATA_EVT:
             log_i("ESP_BT_GAP_CONFIG_EIR_DATA_EVT: stat:%d num:%d", param->config_eir_data.stat, param->config_eir_data.eir_type_num);
             break;
 
+        case ESP_BT_GAP_SET_AFH_CHANNELS_EVT:
+            log_i("ESP_BT_GAP_SET_AFH_CHANNELS_EVT Set AFH channels event");
+            break;
+
         case ESP_BT_GAP_READ_REMOTE_NAME_EVT:
             if (param->read_rmt_name.stat == ESP_BT_STATUS_SUCCESS ) {
                 log_i("ESP_BT_GAP_READ_REMOTE_NAME_EVT: %s", param->read_rmt_name.rmt_name);
@@ -583,6 +591,22 @@ static void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *pa
             log_i("ESP_BT_GAP_MODE_CHG_EVT: mode: %d", param->mode_chg.mode);
             break;
 
+        case ESP_BT_GAP_REMOVE_BOND_DEV_COMPLETE_EVT:
+            log_i("ESP_BT_GAP_REMOVE_BOND_DEV_COMPLETE_EVT remove bond device complete event");
+            break;
+
+        case ESP_BT_GAP_QOS_CMPL_EVT:
+            log_i("ESP_BT_GAP_QOS_CMPL_EVT QOS complete event");
+            break;
+
+        case ESP_BT_GAP_ACL_CONN_CMPL_STAT_EVT:
+            log_i("ESP_BT_GAP_ACL_CONN_CMPL_STAT_EVT ACL connection complete status event");
+            break;
+
+        case ESP_BT_GAP_ACL_DISCONN_CMPL_STAT_EVT:
+            log_i("ESP_BT_GAP_ACL_DISCONN_CMPL_STAT_EVT ACL disconnection complete status event");
+            break;
+
         default:
             log_i("ESP-BT_GAP_* unknown message: %d", event);
             break;
@@ -893,7 +917,7 @@ esp_err_t BluetoothSerial::register_callback(esp_spp_cb_t * callback)
     return ESP_OK;
 }
 
-//Simple Secure Pairing
+// Simple Secure Pairing
 void BluetoothSerial::enableSSP() {
     _enableSSP = true;
 }
@@ -1211,4 +1235,5 @@ BTAddress BluetoothSerial::getBtAddressObject() {
 String BluetoothSerial::getBtAddressString() {
     return getBtAddressObject().toString(true);
 }
-#endif
+
+#endif // defined(CONFIG_BT_ENABLED) && defined(CONFIG_BLUEDROID_ENABLED)

From 64595003c306f69533dcac565ebe08304238b8e1 Mon Sep 17 00:00:00 2001
From: Tomas Pilny <tomas.pilny@espressif.com>
Date: Mon, 24 Jul 2023 17:20:27 +0200
Subject: [PATCH 04/14] Implemented dropCache() method to remove bonded devices

---
 .../SerialToSerialBT/SerialToSerialBT.ino     | 14 +++--
 .../SerialToSerialBTM/SerialToSerialBTM.ino   | 10 +++-
 .../BluetoothSerial/src/BluetoothSerial.cpp   | 57 +++++++++++++++++--
 .../BluetoothSerial/src/BluetoothSerial.h     |  1 +
 4 files changed, 71 insertions(+), 11 deletions(-)

diff --git a/libraries/BluetoothSerial/examples/SerialToSerialBT/SerialToSerialBT.ino b/libraries/BluetoothSerial/examples/SerialToSerialBT/SerialToSerialBT.ino
index 5027ae6a7e3..fdfebbad34c 100644
--- a/libraries/BluetoothSerial/examples/SerialToSerialBT/SerialToSerialBT.ino
+++ b/libraries/BluetoothSerial/examples/SerialToSerialBT/SerialToSerialBT.ino
@@ -11,12 +11,14 @@ const char *pin = "1234"; // Change this to more secure PIN.
 
 String device_name = "ESP32-BT-Slave";
 
+// Check if BlueTooth is available
 #if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
-#error Bluetooth is not enabled! Please run `make menuconfig` to and enable it
+  #error Bluetooth is not enabled! Please run `make menuconfig` to and enable it
 #endif
 
+// Check Serial Port Profile
 #if !defined(CONFIG_BT_SPP_ENABLED)
-#error Serial Bluetooth not available or not enabled. It is only available for the ESP32 chip.
+  #error Serial Port Profile for BlueTooth is not available or not enabled. It is only available for the ESP32 chip.
 #endif
 
 BluetoothSerial SerialBT;
@@ -24,11 +26,15 @@ BluetoothSerial SerialBT;
 void setup() {
   Serial.begin(115200);
   SerialBT.begin(device_name); //Bluetooth device name
+  //SerialBT.dropCache();
   Serial.printf("The device with name \"%s\" is started.\nNow you can pair it with Bluetooth!\n", device_name.c_str());
   //Serial.printf("The device with name \"%s\" and MAC address %s is started.\nNow you can pair it with Bluetooth!\n", device_name.c_str(), SerialBT.getMacString()); // Use this after the MAC method is implemented
   #ifdef USE_PIN
-    SerialBT.setPin(pin);
-    Serial.println("Using PIN");
+    if(!SerialBT.setPin(pin)){
+      Serial.println("Error while setting PIN!");
+    }else{
+      Serial.printf("Using PIN: %s\n", pin);
+    }
   #endif
 }
 
diff --git a/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino b/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino
index d71941b002d..032ead60b7e 100644
--- a/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino
+++ b/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino
@@ -18,10 +18,15 @@
 #define USE_NAME // Comment this to use MAC address instead of a slaveName
 const char *pin = "1234"; // Change this to reflect the pin expected by the real slave BT device
 
-#if !defined(CONFIG_BT_SPP_ENABLED)
-#error Serial Bluetooth not available or not enabled. It is only available for the ESP32 chip.
+// Check if BlueTooth is available
+#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
+  #error Bluetooth is not enabled! Please run `make menuconfig` to and enable it
 #endif
 
+// Check Serial Port Profile
+#if !defined(CONFIG_BT_SPP_ENABLED)
+  #error Serial Port Profile for BlueTooth is not available or not enabled. It is only available for the ESP32 chip.
+#endif
 BluetoothSerial SerialBT;
 
 #ifdef USE_NAME
@@ -38,6 +43,7 @@ void setup() {
   Serial.begin(115200);
 
   SerialBT.begin(myName, true);
+  //SerialBT.dropCache();
   Serial.printf("The device \"%s\" started in master mode, make sure slave BT device is on!\n", myName.c_str());
 
   #ifndef USE_NAME
diff --git a/libraries/BluetoothSerial/src/BluetoothSerial.cpp b/libraries/BluetoothSerial/src/BluetoothSerial.cpp
index 8f54de66a27..fcbcf8025c6 100644
--- a/libraries/BluetoothSerial/src/BluetoothSerial.cpp
+++ b/libraries/BluetoothSerial/src/BluetoothSerial.cpp
@@ -956,8 +956,8 @@ bool BluetoothSerial::connect(String remoteName)
     disconnect();
     _doConnect = true;
     _isRemoteAddressSet = false;
-	_sec_mask = ESP_SPP_SEC_ENCRYPT|ESP_SPP_SEC_AUTHENTICATE;
-	_role = ESP_SPP_ROLE_MASTER;
+    _sec_mask = ESP_SPP_SEC_ENCRYPT|ESP_SPP_SEC_AUTHENTICATE;
+    _role = ESP_SPP_ROLE_MASTER;
     strncpy(_remote_name, remoteName.c_str(), ESP_BT_GAP_MAX_BDNAME_LEN);
     _remote_name[ESP_BT_GAP_MAX_BDNAME_LEN] = 0;
     log_i("master : remoteName");
@@ -998,8 +998,8 @@ bool BluetoothSerial::connect(uint8_t remoteAddress[], int channel, esp_spp_sec_
     _doConnect = true;
     _remote_name[0] = 0;
     _isRemoteAddressSet = true;
-	_sec_mask = sec_mask;
-	_role = role;
+    _sec_mask = sec_mask;
+    _role = role;
     memcpy(_peer_bd_addr, remoteAddress, ESP_BD_ADDR_LEN);
     log_i("master : remoteAddress");
     xEventGroupClearBits(_spp_event_group, SPP_CLOSED);
@@ -1011,7 +1011,7 @@ bool BluetoothSerial::connect(uint8_t remoteAddress[], int channel, esp_spp_sec_
             channel);
 #endif
         if(esp_spp_connect(sec_mask, role, channel, _peer_bd_addr) != ESP_OK ) {
-			log_e("spp connect failed");
+            log_e("spp connect failed");
       retval = false;
     } else {
       retval = waitForConnect(READY_TIMEOUT);
@@ -1236,4 +1236,51 @@ String BluetoothSerial::getBtAddressString() {
     return getBtAddressObject().toString(true);
 }
 
+void BluetoothSerial::dropCache(){
+    if(!isReady(false, READY_TIMEOUT)){
+        log_w("Attempted to drop cache for uninitialized driver. First call begin()");
+        return;
+    }
+
+    int expected_dev_num = esp_bt_gap_get_bond_device_num();
+    if(expected_dev_num == 0){
+        log_i("No devices in cache.");
+        return;
+    }else{
+        log_d("Found %d bonded devices", expected_dev_num);
+    }
+    esp_err_t ret;
+
+    // typedef uint8_t esp_bd_addr_t[ESP_BD_ADDR_LEN] // ESP_BD_ADDR_LEN = 6
+    esp_bd_addr_t *dev_list = NULL;
+    log_d("Allocate buffer: sizeof(esp_bd_addr_t)=%d * expected_dev_num=%d", sizeof(esp_bd_addr_t), expected_dev_num);
+    dev_list = (esp_bd_addr_t*) malloc(sizeof(esp_bd_addr_t) * expected_dev_num);
+    if(dev_list == NULL){
+        log_e("Could not allocated BT device buffer!");
+        return;
+    }
+    //uint8_t dev_list [20][6];
+
+    int dev_num;
+    ret = esp_bt_gap_get_bond_device_list(&dev_num, dev_list);
+    log_d("esp_bt_gap_get_bond_device_list ret = %d", ret);
+    if(ret == ESP_OK){
+        if(dev_num != expected_dev_num){
+            log_w("Inconsistent number of bonded devices. Expected %d; returned %d",expected_dev_num, dev_num);
+        }
+        for(int i=0; i<dev_num; ++i){
+            ret = esp_bt_gap_remove_bond_device(dev_list[i]);
+            log_d("esp_bt_gap_remove_bond_device ret = %d", ret);
+            if(ret == ESP_OK){
+                log_d("Removed bonded device #%d", i);
+            }else{
+                log_w("Failed to removed bonded device #%d", i);
+            }
+            //btc_storage_remove_bonded_device(dev_list[i]);
+        }
+        log_d("device num after delete = %d", esp_bt_gap_get_bond_device_num());
+    }else{
+        log_w("Function esp_bt_gap_get_bond_device_list() returned code %d", ret);
+    }
+}
 #endif // defined(CONFIG_BT_ENABLED) && defined(CONFIG_BLUEDROID_ENABLED)
diff --git a/libraries/BluetoothSerial/src/BluetoothSerial.h b/libraries/BluetoothSerial/src/BluetoothSerial.h
index a9fc26dc1f2..8749c849dae 100644
--- a/libraries/BluetoothSerial/src/BluetoothSerial.h
+++ b/libraries/BluetoothSerial/src/BluetoothSerial.h
@@ -88,6 +88,7 @@ class BluetoothSerial: public Stream
         void getBtAddress(uint8_t *mac);
         BTAddress getBtAddressObject();
         String getBtAddressString();
+        void dropCache();
     private:
         String local_name;
         int timeoutTicks=0;

From cb137451c5d2f0dd1939e6b87e36077466c39940 Mon Sep 17 00:00:00 2001
From: Tomas Pilny <tomas.pilny@espressif.com>
Date: Wed, 2 Aug 2023 14:42:05 +0200
Subject: [PATCH 05/14] Removed legacy pairing, enhaced SSP

---
 .../SerialToSerialBT/SerialToSerialBT.ino     |  14 +-
 .../SerialToSerialBTM/SerialToSerialBTM.ino   |   3 +-
 .../SerialToSerialBT_SSP.ino                  | 124 +++++++++++-------
 .../BluetoothSerial/src/BluetoothSerial.cpp   | 119 +++++++++--------
 .../BluetoothSerial/src/BluetoothSerial.h     |   8 +-
 5 files changed, 147 insertions(+), 121 deletions(-)

diff --git a/libraries/BluetoothSerial/examples/SerialToSerialBT/SerialToSerialBT.ino b/libraries/BluetoothSerial/examples/SerialToSerialBT/SerialToSerialBT.ino
index fdfebbad34c..ea38d2838f7 100644
--- a/libraries/BluetoothSerial/examples/SerialToSerialBT/SerialToSerialBT.ino
+++ b/libraries/BluetoothSerial/examples/SerialToSerialBT/SerialToSerialBT.ino
@@ -6,9 +6,6 @@
 
 #include "BluetoothSerial.h"
 
-//#define USE_PIN // Uncomment this to use PIN during pairing. The pin is specified on the line below
-const char *pin = "1234"; // Change this to more secure PIN.
-
 String device_name = "ESP32-BT-Slave";
 
 // Check if BlueTooth is available
@@ -25,17 +22,10 @@ BluetoothSerial SerialBT;
 
 void setup() {
   Serial.begin(115200);
+  SerialBT.enableSSP(true, false);
   SerialBT.begin(device_name); //Bluetooth device name
-  //SerialBT.dropCache();
+  //SerialBT.dropCache(); // Uncomment this to delete paired devices; Must be called after begin
   Serial.printf("The device with name \"%s\" is started.\nNow you can pair it with Bluetooth!\n", device_name.c_str());
-  //Serial.printf("The device with name \"%s\" and MAC address %s is started.\nNow you can pair it with Bluetooth!\n", device_name.c_str(), SerialBT.getMacString()); // Use this after the MAC method is implemented
-  #ifdef USE_PIN
-    if(!SerialBT.setPin(pin)){
-      Serial.println("Error while setting PIN!");
-    }else{
-      Serial.printf("Using PIN: %s\n", pin);
-    }
-  #endif
 }
 
 void loop() {
diff --git a/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino b/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino
index 032ead60b7e..d0b253e76b3 100644
--- a/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino
+++ b/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino
@@ -16,7 +16,6 @@
 #include "BluetoothSerial.h"
 
 #define USE_NAME // Comment this to use MAC address instead of a slaveName
-const char *pin = "1234"; // Change this to reflect the pin expected by the real slave BT device
 
 // Check if BlueTooth is available
 #if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
@@ -43,7 +42,7 @@ void setup() {
   Serial.begin(115200);
 
   SerialBT.begin(myName, true);
-  //SerialBT.dropCache();
+  //SerialBT.dropCache(); // Uncomment this to delete paired devices; Must be called after begin
   Serial.printf("The device \"%s\" started in master mode, make sure slave BT device is on!\n", myName.c_str());
 
   #ifndef USE_NAME
diff --git a/libraries/BluetoothSerial/examples/SerialToSerialBT_SSP/SerialToSerialBT_SSP.ino b/libraries/BluetoothSerial/examples/SerialToSerialBT_SSP/SerialToSerialBT_SSP.ino
index 8934fae3ee1..179858a544d 100644
--- a/libraries/BluetoothSerial/examples/SerialToSerialBT_SSP/SerialToSerialBT_SSP.ino
+++ b/libraries/BluetoothSerial/examples/SerialToSerialBT_SSP/SerialToSerialBT_SSP.ino
@@ -10,7 +10,7 @@
 
 #include "BluetoothSerial.h"
 
-//#define AUTO_PAIR // Uncomment to skip the terminal confirmation.
+//#define AUTO_PAIR // Uncomment to automatically authenticate ESP32 side
 
 // Check if BlueTooth is available
 #if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
@@ -29,82 +29,106 @@
 
 const char * deviceName = "ESP32_SSP_example";
 
+// The following lines defines the method of pairing
+// When both Input and Output are false only the other device authenticates pairing without any pin.
+// When Output is true and Input is false only the other device authenticates pairing without any pin.
+// When both Input and Output are true both devices display randomly generated code and if they match authenticate pairing on both devices
+//   - On ESP must be implemented by calling creating callback via onConfirmRequest() and in this callback request user input and call SerialBT.confirmReply(true); if the authenticated.
+// When Input is true and Output is false User will be required to input the passkey (displayed on the other device) to the ESP32 device to authenticate.
+const bool INUPT_CAPABILITY = false; // Defines if ESP32 device has input method (Serial terminal, keyboard or similar)
+const bool OUTPUT_CAPABILITY = true; // Defines if ESP32 device has output method (Serial terminal, display or similar)
+
 BluetoothSerial SerialBT;
-boolean confirmRequestPending = true;
+bool confirmRequestDone = false;
 
-void BTConfirmRequestCallback(uint32_t numVal)
-{
-  confirmRequestPending = true;
+void BTConfirmRequestCallback(uint32_t numVal){
+  confirmRequestDone = false;
 #ifndef AUTO_PAIR
-  Serial.printf("The PIN is: %lu. If it matches number displayed on the other device write \'Y\' or \'y\':\n", numVal);
+  Serial.printf("The PIN is: %06lu. If it matches number displayed on the other device write \'Y\' or \'y\':\n", numVal); // Note the formatting "%06lu" - PIN can start with zero(s) which would be ignored with simple "%lu"
+  while (!Serial.available()) {
+      delay(1); // Feed the watchdog
+      // Wait until data is available on the Serial port.
+    }
+    Serial.printf("Oh you sent %d Bytes, lets see...", Serial.available());
+    int dat = Serial.read();
+    if (dat == 'Y' || dat == 'y'){
+      SerialBT.confirmReply(true);
+    }
+    else{
+      SerialBT.confirmReply(false);
+    }
 #else
   SerialBT.confirmReply(true);
 #endif
 }
 
-void BTAuthCompleteCallback(boolean success)
-{
-  confirmRequestPending = false;
-  if (success)
-  {
+void BTKeyRequestCallback(){
+  Serial.println("BTKeyRequestCallback"); // debug
+  char buffer[7] = {0}; // 6 bytes for number, one for termination '0'
+  while (1) {
+    Serial.print("Enter the passkey displayed on the other device: ");
+    while (!Serial.available()) {
+      delay(1); // Feed the watchdog
+      // Wait until data is available on the Serial port.
+    }
+    size_t len = Serial.readBytesUntil('\n', buffer, sizeof(buffer) - 1);
+    buffer[len] = '\0'; // Null-terminate the string.
+    try {
+      uint32_t passkey = std::stoi(buffer);
+      Serial.printf("Entered PIN: %lu\n", passkey);
+      SerialBT.respondPasskey(passkey);
+      return;
+    } catch (...) {
+      Serial.print("Wrong PIN! Try again.");
+    } // try
+  } // while(1)
+}
+
+void BTAuthCompleteCallback(boolean success){
+  Serial.printf("BTAuthCompleteCallback(boolean success=%d)", success);
+  if (success){
+    confirmRequestDone = true;
     Serial.println("Pairing success!!");
   }
-  else
-  {
+  else{
     Serial.println("Pairing failed, rejected by user!!");
   }
 }
 
 void serial_response(){
-  if (Serial.available())
-    {
+  if (Serial.available()){
       SerialBT.write(Serial.read());
     }
-    if (SerialBT.available())
-    {
+    if (SerialBT.available()){
       Serial.write(SerialBT.read());
     }
     delay(20);
 }
 
-void setup()
-{
+void setup(){
   Serial.begin(115200);
-  SerialBT.enableSSP();
-  SerialBT.dropCache();
+  SerialBT.enableSSP(INUPT_CAPABILITY, OUTPUT_CAPABILITY); // Must be called before begin
   SerialBT.onConfirmRequest(BTConfirmRequestCallback);
+  SerialBT.onKeyRequest(BTKeyRequestCallback);
   SerialBT.onAuthComplete(BTAuthCompleteCallback);
-  SerialBT.begin(deviceName); //Bluetooth device name
-#ifndef AUTO_PAIR
-  Serial.printf("The device started with name \"%s\", now you can pair it with Bluetooth!\nIf the numbers in terminal and on the other device match, press \"Pair\" in phone/computer and write \'Y\' or \'y\' in terminal\n", deviceName);
-#else
-  Serial.printf("The device started with name \"%s\", now you can pair it with Bluetooth!\nIf the numbers in terminal and on the other device match, press \"Pair\" in phone/computer.\n", deviceName);
-#endif
+  SerialBT.begin(deviceName); // Initiate Bluetooth device with name in parameter
+  //SerialBT.dropCache(); // Uncomment this to delete paired devices; Must be called after begin
+  Serial.printf("The device started with name \"%s\", now you can pair it with Bluetooth!\n", deviceName);
+  if(INUPT_CAPABILITY and OUTPUT_CAPABILITY){
+    Serial.println("Both devices will display randomly generated code and if they match authenticate pairing on both devices");
+  }else if(not INUPT_CAPABILITY and not OUTPUT_CAPABILITY){
+    Serial.println("Authenticate pairing on the other device. No PIN is used");
+  }else if(not INUPT_CAPABILITY and OUTPUT_CAPABILITY){
+    Serial.println("Authenticate pairing on the other device. No PIN is used");
+  }else if(INUPT_CAPABILITY and not OUTPUT_CAPABILITY){
+    Serial.println("After pairing is initiated you will be required to enter the passkey to the ESP32 device to authenticate\n > The Passkey will displayed on the other device");
+  }
 }
 
-void loop()
-{
-#ifndef AUTO_PAIR
-  if (confirmRequestPending)
-  {
-    if (Serial.available())
-    {
-      int dat = Serial.read();
-      if (dat == 'Y' || dat == 'y')
-      {
-        SerialBT.confirmReply(true);
-      }
-      else
-      {
-        SerialBT.confirmReply(false);
-      }
-    }
-  }
-  else
-  {
+void loop(){
+  if (confirmRequestDone){
     serial_response();
+  }else{
+    delay(1); // Feed the watchdog
   }
-#else
-  serial_response();
-#endif
 }
diff --git a/libraries/BluetoothSerial/src/BluetoothSerial.cpp b/libraries/BluetoothSerial/src/BluetoothSerial.cpp
index fcbcf8025c6..e84e2e71c8f 100644
--- a/libraries/BluetoothSerial/src/BluetoothSerial.cpp
+++ b/libraries/BluetoothSerial/src/BluetoothSerial.cpp
@@ -58,6 +58,7 @@ static esp_spp_cb_t * custom_spp_callback = NULL;
 static BluetoothSerialDataCb custom_data_callback = NULL;
 static esp_bd_addr_t current_bd_addr;
 static ConfirmRequestCb confirm_request_callback = NULL;
+static KeyRequestCb key_request_callback = NULL;
 static AuthCompleteCb auth_complete_callback = NULL;
 
 #define INQ_LEN 0x10
@@ -68,10 +69,9 @@ static esp_bd_addr_t _peer_bd_addr;
 static char _remote_name[ESP_BT_GAP_MAX_BDNAME_LEN + 1];
 static bool _isRemoteAddressSet;
 static bool _isMaster;
-static esp_bt_pin_code_t _pin_code;
-static int _pin_len;
-static bool _isPinSet;
 static bool _enableSSP;
+static bool _IO_CAP_INPUT;
+static bool _IO_CAP_OUTPUT;
 static esp_spp_sec_t _sec_mask;
 static esp_spp_role_t _role;
 // start connect on ESP_SPP_DISCOVERY_COMP_EVT or save entry for getChannels
@@ -139,22 +139,6 @@ static bool get_name_from_eir(uint8_t *eir, char *bdname, uint8_t *bdname_len)
     return false;
 }
 
-static bool btSetPin() {
-    esp_bt_pin_type_t pin_type;
-    if (_isPinSet) {
-        if (_pin_len) {
-            log_i("pin set");
-            pin_type = ESP_BT_PIN_TYPE_FIXED;
-        } else {
-            _isPinSet = false;
-            log_i("pin reset");
-            pin_type = ESP_BT_PIN_TYPE_VARIABLE; // pin_code would be ignored (default)
-        }
-        return (esp_bt_gap_set_pin(pin_type, _pin_len, _pin_code) == ESP_OK);        
-    }
-    return false;
-}
-
 static esp_err_t _spp_queue_packet(uint8_t *data, size_t len){
     if(!data || !len){
         log_w("No data provided");
@@ -525,7 +509,7 @@ static void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *pa
                     auth_complete_callback(true);
                 }
             } else {
-                log_e("authentication failed, status:%d", param->auth_cmpl.stat);
+                log_e("authentication failed for connecting with \"%s\", status:%d", param->auth_cmpl.device_name, param->auth_cmpl.stat);
                 if (auth_complete_callback) {
                     auth_complete_callback(false);
                 }
@@ -555,7 +539,8 @@ static void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *pa
                 confirm_request_callback(param->cfm_req.num_val);
             }
             else {
-                esp_bt_gap_ssp_confirm_reply(param->cfm_req.bda, true);
+                log_w("ESP_BT_GAP_CFM_REQ_EVT: confirm_request_callback does not exist - refusing pairing");
+                esp_bt_gap_ssp_confirm_reply(param->cfm_req.bda, false);
             }
             break;
 
@@ -565,6 +550,14 @@ static void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *pa
 
         case ESP_BT_GAP_KEY_REQ_EVT:
             log_i("ESP_BT_GAP_KEY_REQ_EVT Please enter passkey!");
+            if (key_request_callback) {
+                memcpy(current_bd_addr, param->cfm_req.bda, sizeof(esp_bd_addr_t));
+                key_request_callback();
+            }
+            else {
+                log_w("ESP_BT_GAP_KEY_REQ_EVT: key_request_callback does not exist - refuseing pairing");
+                esp_bt_gap_ssp_confirm_reply(param->cfm_req.bda, false);
+            }
             break;
 
         case ESP_BT_GAP_READ_RSSI_DELTA_EVT:
@@ -604,7 +597,7 @@ static void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *pa
             break;
 
         case ESP_BT_GAP_ACL_DISCONN_CMPL_STAT_EVT:
-            log_i("ESP_BT_GAP_ACL_DISCONN_CMPL_STAT_EVT ACL disconnection complete status event");
+            log_i("ESP_BT_GAP_ACL_DISCONN_CMPL_STAT_EVT ACL disconnection complete status event: reason %d, handle %d", param->acl_disconn_cmpl_stat.reason, param->acl_disconn_cmpl_stat.handle);
             break;
 
         default:
@@ -702,22 +695,22 @@ static bool _init_bt(const char *deviceName)
         return false;
     }
 
-    // if (esp_bt_sleep_disable() != ESP_OK){
-    //     log_e("esp_bt_sleep_disable failed");
-    // }
-
     log_i("device name set");
     esp_bt_dev_set_device_name(deviceName);
 
-    if (_isPinSet) {
-        log_i("pin set");
-        btSetPin();
-    }
-
     if (_enableSSP) {
         log_i("Simple Secure Pairing");
         esp_bt_sp_param_t param_type = ESP_BT_SP_IOCAP_MODE;
-        esp_bt_io_cap_t iocap = ESP_BT_IO_CAP_IO;
+        esp_bt_io_cap_t iocap;
+        if(_IO_CAP_INPUT && _IO_CAP_OUTPUT){
+            iocap = ESP_BT_IO_CAP_IO; // Display with prompt
+        }else if(!_IO_CAP_INPUT && _IO_CAP_OUTPUT){
+            iocap = ESP_BT_IO_CAP_OUT; // DisplayOnly
+        }else if(_IO_CAP_INPUT && !_IO_CAP_OUTPUT){
+            iocap = ESP_BT_IO_CAP_IN; // Input only
+        }else if(!_IO_CAP_INPUT && !_IO_CAP_OUTPUT){
+            iocap = ESP_BT_IO_CAP_NONE; // No input/output
+        }
         esp_bt_gap_set_security_param(param_type, &iocap, sizeof(uint8_t));
     }
 
@@ -900,6 +893,15 @@ void BluetoothSerial::onConfirmRequest(ConfirmRequestCb cb)
     confirm_request_callback = cb;
 }
 
+void BluetoothSerial::onKeyRequest(KeyRequestCb cb)
+{
+    key_request_callback = cb;
+}
+
+void BluetoothSerial::respondPasskey(uint32_t passkey){
+    esp_bt_gap_ssp_passkey_reply(current_bd_addr, true, passkey);
+}
+
 void BluetoothSerial::onAuthComplete(AuthCompleteCb cb)
 {
     auth_complete_callback = cb;
@@ -907,7 +909,7 @@ void BluetoothSerial::onAuthComplete(AuthCompleteCb cb)
 
 void BluetoothSerial::confirmReply(boolean confirm)
 {
-    esp_bt_gap_ssp_confirm_reply(current_bd_addr, confirm);  
+    esp_bt_gap_ssp_confirm_reply(current_bd_addr, confirm);
 }
 
 
@@ -917,31 +919,38 @@ esp_err_t BluetoothSerial::register_callback(esp_spp_cb_t * callback)
     return ESP_OK;
 }
 
-// Simple Secure Pairing
+// Enable Simple Secure Pairing (using generated PIN)
+// This must be called before calling begin, otherwise has no effect!
 void BluetoothSerial::enableSSP() {
+    if(isReady(false, READY_TIMEOUT)){
+        log_i("Attempted to enable SSP for already initialized driver. Restart to take effect with end() followed by begin()");
+        return;
+    }
     _enableSSP = true;
+    _IO_CAP_INPUT = true;
+    _IO_CAP_OUTPUT = true;
 }
-/*
-     * Set default parameters for Legacy Pairing
-     * Use fixed pin code
-*/
-bool BluetoothSerial::setPin(const char *pin) {
-    log_i("pin: %s", pin);
-    bool isEmpty =  !(pin  && *pin);
-    if (isEmpty && !_isPinSet) {
-        return true; // nothing to do
-    } else if (!isEmpty){
-        _pin_len = strlen(pin);
-        memcpy(_pin_code, pin, _pin_len);
-    } else {
-        _pin_len = 0; // resetting pin to none (default)
-    }
-    _pin_code[_pin_len] = 0;
-    _isPinSet = true;
-    if (isReady(false, READY_TIMEOUT)) {
-        btSetPin();
-    }
-    return true;
+
+// Enable Simple Secure Pairing (using generated PIN)
+// This must be called before calling begin, otherwise has no effect!
+// Behavior description:
+// When both Input and Output are false only the other device authenticates pairing without any pin.
+// When Output is true and Input is false only the other device authenticates pairing without any pin.
+// When both Input and Output are true both devices display randomly generated code and if they match authenticate pairing on both devices
+//   - On ESP must be implemented by calling creating callback via onConfirmRequest() and in this callback request user input and call SerialBT.confirmReply(true); if the authenticated.
+// When Input is true and Output is false User will be required to input the passkey to the ESP32 device to authenticate.
+//   - This must be implemented by user - register callback: onKeyRequest() in which call SerialBT.respondPasskey(passkey);
+void BluetoothSerial::enableSSP(bool inputCpability, bool outputCapability) {
+    log_i("Enabling SSP: input capability=%d; output capability=%d", inputCpability, outputCapability);
+    _enableSSP = true;
+    _IO_CAP_INPUT = inputCpability;
+    _IO_CAP_OUTPUT = outputCapability;
+}
+
+// Disable Simple Secure Pairing (using generated PIN)
+// This must be called before calling begin, otherwise has no effect!
+void BluetoothSerial::disableSSP() {
+    _enableSSP = false;
 }
 
 bool BluetoothSerial::connect(String remoteName)
diff --git a/libraries/BluetoothSerial/src/BluetoothSerial.h b/libraries/BluetoothSerial/src/BluetoothSerial.h
index 8749c849dae..44c234eb63b 100644
--- a/libraries/BluetoothSerial/src/BluetoothSerial.h
+++ b/libraries/BluetoothSerial/src/BluetoothSerial.h
@@ -29,6 +29,7 @@
 
 typedef std::function<void(const uint8_t *buffer, size_t size)> BluetoothSerialDataCb;
 typedef std::function<void(uint32_t num_val)> ConfirmRequestCb;
+typedef std::function<void()> KeyRequestCb;
 typedef std::function<void(boolean success)> AuthCompleteCb;
 typedef std::function<void(BTAdvertisedDevice* pAdvertisedDevice)> BTAdvertisedDeviceCb;
 
@@ -56,15 +57,18 @@ class BluetoothSerial: public Stream
         esp_err_t register_callback(esp_spp_cb_t * callback);
         
         void onConfirmRequest(ConfirmRequestCb cb);
+        void onKeyRequest(KeyRequestCb cb);
+        void respondPasskey(uint32_t passkey);
         void onAuthComplete(AuthCompleteCb cb);
         void confirmReply(boolean confirm);
 
         void enableSSP();
-        bool setPin(const char *pin);
+        void enableSSP(bool inputCapability, bool outputCapability);
+        void disableSSP();
         bool connect(String remoteName);
         bool connect(uint8_t remoteAddress[], int channel=0, esp_spp_sec_t sec_mask=(ESP_SPP_SEC_ENCRYPT|ESP_SPP_SEC_AUTHENTICATE), esp_spp_role_t role=ESP_SPP_ROLE_MASTER);
         bool connect(const BTAddress &remoteAddress, int channel=0, esp_spp_sec_t sec_mask=(ESP_SPP_SEC_ENCRYPT|ESP_SPP_SEC_AUTHENTICATE), esp_spp_role_t role=ESP_SPP_ROLE_MASTER) {
-			return connect(*remoteAddress.getNative(), channel, sec_mask); };
+            return connect(*remoteAddress.getNative(), channel, sec_mask); };
         bool connect();
         bool connected(int timeout=0);
         bool isClosed();

From d5a1bbcab6d22548187fea3670977c5e112db86c Mon Sep 17 00:00:00 2001
From: Tomas Pilny <tomas.pilny@espressif.com>
Date: Wed, 2 Aug 2023 15:04:12 +0200
Subject: [PATCH 06/14] Minor updates to examples

---
 .../examples/SerialToSerialBT/SerialToSerialBT.ino     | 10 +++++-----
 .../examples/SerialToSerialBTM/SerialToSerialBTM.ino   |  8 +++++---
 2 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/libraries/BluetoothSerial/examples/SerialToSerialBT/SerialToSerialBT.ino b/libraries/BluetoothSerial/examples/SerialToSerialBT/SerialToSerialBT.ino
index ea38d2838f7..ec78afb9e92 100644
--- a/libraries/BluetoothSerial/examples/SerialToSerialBT/SerialToSerialBT.ino
+++ b/libraries/BluetoothSerial/examples/SerialToSerialBT/SerialToSerialBT.ino
@@ -1,8 +1,9 @@
-//This example code is in the Public Domain (or CC0 licensed, at your option.)
-//By Evandro Copercini - 2018
+// This example code is in the Public Domain (or CC0 licensed, at your option.)
+// By Evandro Copercini - 2018
 //
-//This example creates a bridge between Serial and Classical Bluetooth (SPP)
-//and also demonstrate that SerialBT have the same functionalities of a normal Serial
+// This example creates a bridge between Serial and Classical Bluetooth (SPP)
+// and also demonstrate that SerialBT have the same functionalities of a normal Serial
+// Note: Pairing is authenticated automatically by this device
 
 #include "BluetoothSerial.h"
 
@@ -22,7 +23,6 @@ BluetoothSerial SerialBT;
 
 void setup() {
   Serial.begin(115200);
-  SerialBT.enableSSP(true, false);
   SerialBT.begin(device_name); //Bluetooth device name
   //SerialBT.dropCache(); // Uncomment this to delete paired devices; Must be called after begin
   Serial.printf("The device with name \"%s\" is started.\nNow you can pair it with Bluetooth!\n", device_name.c_str());
diff --git a/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino b/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino
index d0b253e76b3..01fd42281dd 100644
--- a/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino
+++ b/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino
@@ -1,17 +1,19 @@
 // This example code is in the Public Domain (or CC0 licensed, at your option.)
 // By Victor Tchistiak - 2019
 //
-// This example demonstrates master mode Bluetooth connection to a slave BT device using PIN (password)
-// defined either by String "slaveName" by default "OBDII" or by MAC address
+// This example demonstrates master mode Bluetooth connection to a slave BT device
+// defined either by String "slaveName" by default "ESP32-BT-Slave" or by MAC address
 //
 // This example creates a bridge between Serial and Classical Bluetooth (SPP)
 // This is an extension of the SerialToSerialBT example by Evandro Copercini - 2018
 //
 // DO NOT try to connect to phone or laptop - they are master
-// devices, same as the ESP using this code - it will NOT work!
+// devices, same as the ESP using this code - you will be able
+// to pair, but the serial communication will NOT work!
 //
 // You can try to flash a second ESP32 with the example SerialToSerialBT - it should
 // automatically pair with ESP32 running this code
+// Note: Pairing is authenticated automatically by this device
 
 #include "BluetoothSerial.h"
 

From 68c4f3aec8a1c1679ef9c75937a9e3419a00f729 Mon Sep 17 00:00:00 2001
From: Tomas Pilny <tomas.pilny@espressif.com>
Date: Wed, 2 Aug 2023 16:11:41 +0200
Subject: [PATCH 07/14] Updated README + asociated comments in source and
 example

---
 libraries/BluetoothSerial/README.md           | 64 ++++++++++++++++---
 .../SerialToSerialBT_SSP.ino                  |  8 ++-
 .../BluetoothSerial/src/BluetoothSerial.cpp   |  5 +-
 3 files changed, 64 insertions(+), 13 deletions(-)

diff --git a/libraries/BluetoothSerial/README.md b/libraries/BluetoothSerial/README.md
index 9d25dbca0a9..4bcf353ba4e 100644
--- a/libraries/BluetoothSerial/README.md
+++ b/libraries/BluetoothSerial/README.md
@@ -1,19 +1,67 @@
-### Bluetooth Serial Library
+## Bluetooth Serial Library
 
-A simple Serial compatible library using ESP32 classical bluetooth (SPP)
+A simple Serial compatible library using ESP32 classical Bluetooth Serial Port Profile (SPP)
 
+Note: Since version 3.0.0 this library does not support legacy pairing (using fixed PIN consisting of 4 digits).
 
+### How to use it?
 
-#### How to use it?
+There are 3 basic use cases: phone, other ESP32 or any MCU with BT serial module
 
-- Download one bluetooth terminal app in your smartphone<br>
-For Android: https://play.google.com/store/apps/details?id=de.kai_morich.serial_bluetooth_terminal <br>
-For iOS: https://itunes.apple.com/us/app/hm10-bluetooth-serial-lite/id1030454675
+#### Phone
+
+- Download one of the Bluetooth terminal apps to your smartphone
+
+    - For [Android](https://play.google.com/store/apps/details?id=de.kai_morich.serial_bluetooth_terminal)
+    - For [iOS](https://itunes.apple.com/us/app/hm10-bluetooth-serial-lite/id1030454675)
 
 - Flash an example sketch to your ESP32
 
-- Scan and pair the device in your smartphone
+- Scan and pair the device to your smartphone
 
-- Open the bluetooth terminal app
+- Open the Bluetooth terminal app and connect
 
 - Enjoy
+
+#### ESP32
+
+You can flash one of the ESP32 with example [`SerialToSerialBTM`](https://github.com/espressif/arduino-esp32/blob/master/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino) (the Master) and another ESP32 with [`SerialToSerialBT`](https://github.com/espressif/arduino-esp32/blob/master/libraries/BluetoothSerial/examples/SerialToSerialBT/SerialToSerialBT.ino) (the Slave).
+Those examples are pre-set to work out-of-the box but they should be scalable to connect multiple Slaves to the Master.
+
+#### 3rd party Serial BT module
+
+Using 3rd party Serial BT module will require to study the documentation of the particular module in order to make it work, however one side can utilize the mentioned [`SerialToSerialBTM`](https://github.com/espressif/arduino-esp32/blob/master/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino) (the Master) or [`SerialToSerialBT`](https://github.com/espressif/arduino-esp32/blob/master/libraries/BluetoothSerial/examples/SerialToSerialBT/SerialToSerialBT.ino) (the Slave).
+
+### Pairing options
+
+There are two major options - with and without Secure Simple Pairing (SSP).
+
+#### Without SSP
+
+This method will authenticate automatically any attempt to pair and should not be used if security is a concern! This option is used for the examples [`SerialToSerialBTM`](https://github.com/espressif/arduino-esp32/blob/master/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino) and [`SerialToSerialBT`](https://github.com/espressif/arduino-esp32/blob/master/libraries/BluetoothSerial/examples/SerialToSerialBT/SerialToSerialBT.ino).
+
+### With SSP
+
+Usage of SSP provides secure connection. This option is demonstrated in example [`SerialToSerialBT_SSP`](https://github.com/espressif/arduino-esp32/blob/master/libraries/BluetoothSerial/examples/SerialToSerialBT_SSP/SerialToSerialBT_SSP.ino)
+
+The Secure Simple Pairing is enable by calling method `enableSSP` which has two variants - one is backward compatible without parameter `enableSSP()` and second with parameters `enableSSP(bool inputCapability, bool outputCapability)`.
+Alternatively the SSP can be disabled by `disableSSP()`
+
+Both options must be called before `begin()` or if it is called after `begin()` the driver needs to be restart (call `end()` followed by `begin()`) in order to take in effect enabling or disabling the SSP.
+
+#### The parameters define the method of authentication:
+
+**inputCapability** - Defines if ESP32 device has input method (Serial terminal, keyboard or similar)
+
+**outputCapability** - Defines if ESP32 device has output method (Serial terminal, display or similar)
+
+* **inputCapability=true and outputCapability=true**
+    * Both devices display randomly generated code and if they match the user will authenticate pairing on both devices.
+    * This must be implemented registering callback via `onConfirmRequest()` and in this callback the user will input the response and call `confirmReply(true)` if the authenticated, otherwise call `confirmReply(false)` to reject the pairing.
+* **inputCapability=false and outputCapability=false**
+    * Only the other device authenticates pairing without any pin.
+* **inputCapability=false and outputCapability=true**
+    * Only the other device authenticates pairing without any pin.
+* **inputCapability=true and outputCapability=false**
+    * User will be required to input the passkey to the ESP32 device to authenticate.
+    * This must be implemented by registering callback via `onKeyRequest()` and in this callback the entered passkey will be responded via `respondPasskey(passkey)`
\ No newline at end of file
diff --git a/libraries/BluetoothSerial/examples/SerialToSerialBT_SSP/SerialToSerialBT_SSP.ino b/libraries/BluetoothSerial/examples/SerialToSerialBT_SSP/SerialToSerialBT_SSP.ino
index 179858a544d..3c83eae95fb 100644
--- a/libraries/BluetoothSerial/examples/SerialToSerialBT_SSP/SerialToSerialBT_SSP.ino
+++ b/libraries/BluetoothSerial/examples/SerialToSerialBT_SSP/SerialToSerialBT_SSP.ino
@@ -30,11 +30,13 @@
 const char * deviceName = "ESP32_SSP_example";
 
 // The following lines defines the method of pairing
-// When both Input and Output are false only the other device authenticates pairing without any pin.
+When both Input and Output are false only the other device authenticates pairing without any pin.
 // When Output is true and Input is false only the other device authenticates pairing without any pin.
 // When both Input and Output are true both devices display randomly generated code and if they match authenticate pairing on both devices
-//   - On ESP must be implemented by calling creating callback via onConfirmRequest() and in this callback request user input and call SerialBT.confirmReply(true); if the authenticated.
-// When Input is true and Output is false User will be required to input the passkey (displayed on the other device) to the ESP32 device to authenticate.
+//   - This must be implemented by registering callback via onConfirmRequest() and in this callback request user input and call confirmReply(true); if the authenticated
+//      otherwise call `confirmReply(false)` to reject the pairing.
+// When Input is true and Output is false User will be required to input the passkey to the ESP32 device to authenticate.
+//   - This must be implemented by registering callback via onKeyRequest() and in this callback the entered passkey will be responded via respondPasskey(passkey);
 const bool INUPT_CAPABILITY = false; // Defines if ESP32 device has input method (Serial terminal, keyboard or similar)
 const bool OUTPUT_CAPABILITY = true; // Defines if ESP32 device has output method (Serial terminal, display or similar)
 
diff --git a/libraries/BluetoothSerial/src/BluetoothSerial.cpp b/libraries/BluetoothSerial/src/BluetoothSerial.cpp
index e84e2e71c8f..94bbf31a2d2 100644
--- a/libraries/BluetoothSerial/src/BluetoothSerial.cpp
+++ b/libraries/BluetoothSerial/src/BluetoothSerial.cpp
@@ -937,9 +937,10 @@ void BluetoothSerial::enableSSP() {
 // When both Input and Output are false only the other device authenticates pairing without any pin.
 // When Output is true and Input is false only the other device authenticates pairing without any pin.
 // When both Input and Output are true both devices display randomly generated code and if they match authenticate pairing on both devices
-//   - On ESP must be implemented by calling creating callback via onConfirmRequest() and in this callback request user input and call SerialBT.confirmReply(true); if the authenticated.
+//   - This must be implemented by registering callback via onConfirmRequest() and in this callback request user input and call confirmReply(true); if the authenticated
+//      otherwise call `confirmReply(false)` to reject the pairing.
 // When Input is true and Output is false User will be required to input the passkey to the ESP32 device to authenticate.
-//   - This must be implemented by user - register callback: onKeyRequest() in which call SerialBT.respondPasskey(passkey);
+//   - This must be implemented by registering callback via onKeyRequest() and in this callback the entered passkey will be responded via respondPasskey(passkey);
 void BluetoothSerial::enableSSP(bool inputCpability, bool outputCapability) {
     log_i("Enabling SSP: input capability=%d; output capability=%d", inputCpability, outputCapability);
     _enableSSP = true;

From 895952f3b4a5599b1e49219146d41afb887b69bd Mon Sep 17 00:00:00 2001
From: Tomas Pilny <tomas.pilny@espressif.com>
Date: Thu, 3 Aug 2023 19:59:11 +0200
Subject: [PATCH 08/14] Implemented more methods to manipulate bonded devices +
 modified example

---
 .../SerialToSerialBT/SerialToSerialBT.ino     |   2 +-
 .../SerialToSerialBTM/SerialToSerialBTM.ino   |   2 +-
 .../SerialToSerialBT_SSP.ino                  |  16 +--
 .../bt_classic_device_discovery.ino           |  14 +-
 .../bt_remove_paired_devices.ino              | 129 ++++++++----------
 .../BluetoothSerial/src/BluetoothSerial.cpp   |  70 +++++++++-
 .../BluetoothSerial/src/BluetoothSerial.h     |   9 +-
 7 files changed, 146 insertions(+), 96 deletions(-)

diff --git a/libraries/BluetoothSerial/examples/SerialToSerialBT/SerialToSerialBT.ino b/libraries/BluetoothSerial/examples/SerialToSerialBT/SerialToSerialBT.ino
index ec78afb9e92..69efeff64c6 100644
--- a/libraries/BluetoothSerial/examples/SerialToSerialBT/SerialToSerialBT.ino
+++ b/libraries/BluetoothSerial/examples/SerialToSerialBT/SerialToSerialBT.ino
@@ -24,7 +24,7 @@ BluetoothSerial SerialBT;
 void setup() {
   Serial.begin(115200);
   SerialBT.begin(device_name); //Bluetooth device name
-  //SerialBT.dropCache(); // Uncomment this to delete paired devices; Must be called after begin
+  //SerialBT.deleteAllBondedDevices(); // Uncomment this to delete paired devices; Must be called after begin
   Serial.printf("The device with name \"%s\" is started.\nNow you can pair it with Bluetooth!\n", device_name.c_str());
 }
 
diff --git a/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino b/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino
index 01fd42281dd..637ab2cd1da 100644
--- a/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino
+++ b/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino
@@ -44,7 +44,7 @@ void setup() {
   Serial.begin(115200);
 
   SerialBT.begin(myName, true);
-  //SerialBT.dropCache(); // Uncomment this to delete paired devices; Must be called after begin
+  //SerialBT.deleteAllBondedDevices(); // Uncomment this to delete paired devices; Must be called after begin
   Serial.printf("The device \"%s\" started in master mode, make sure slave BT device is on!\n", myName.c_str());
 
   #ifndef USE_NAME
diff --git a/libraries/BluetoothSerial/examples/SerialToSerialBT_SSP/SerialToSerialBT_SSP.ino b/libraries/BluetoothSerial/examples/SerialToSerialBT_SSP/SerialToSerialBT_SSP.ino
index 3c83eae95fb..a9d861333a1 100644
--- a/libraries/BluetoothSerial/examples/SerialToSerialBT_SSP/SerialToSerialBT_SSP.ino
+++ b/libraries/BluetoothSerial/examples/SerialToSerialBT_SSP/SerialToSerialBT_SSP.ino
@@ -30,14 +30,14 @@
 const char * deviceName = "ESP32_SSP_example";
 
 // The following lines defines the method of pairing
-When both Input and Output are false only the other device authenticates pairing without any pin.
+// When both Input and Output are false only the other device authenticates pairing without any pin.
 // When Output is true and Input is false only the other device authenticates pairing without any pin.
 // When both Input and Output are true both devices display randomly generated code and if they match authenticate pairing on both devices
 //   - This must be implemented by registering callback via onConfirmRequest() and in this callback request user input and call confirmReply(true); if the authenticated
 //      otherwise call `confirmReply(false)` to reject the pairing.
 // When Input is true and Output is false User will be required to input the passkey to the ESP32 device to authenticate.
 //   - This must be implemented by registering callback via onKeyRequest() and in this callback the entered passkey will be responded via respondPasskey(passkey);
-const bool INUPT_CAPABILITY = false; // Defines if ESP32 device has input method (Serial terminal, keyboard or similar)
+const bool INPUT_CAPABILITY = false; // Defines if ESP32 device has input method (Serial terminal, keyboard or similar)
 const bool OUTPUT_CAPABILITY = true; // Defines if ESP32 device has output method (Serial terminal, display or similar)
 
 BluetoothSerial SerialBT;
@@ -109,20 +109,20 @@ void serial_response(){
 
 void setup(){
   Serial.begin(115200);
-  SerialBT.enableSSP(INUPT_CAPABILITY, OUTPUT_CAPABILITY); // Must be called before begin
+  SerialBT.enableSSP(INPUT_CAPABILITY, OUTPUT_CAPABILITY); // Must be called before begin
   SerialBT.onConfirmRequest(BTConfirmRequestCallback);
   SerialBT.onKeyRequest(BTKeyRequestCallback);
   SerialBT.onAuthComplete(BTAuthCompleteCallback);
   SerialBT.begin(deviceName); // Initiate Bluetooth device with name in parameter
-  //SerialBT.dropCache(); // Uncomment this to delete paired devices; Must be called after begin
+  //SerialBT.deleteAllBondedDevices(); // Uncomment this to delete paired devices; Must be called after begin
   Serial.printf("The device started with name \"%s\", now you can pair it with Bluetooth!\n", deviceName);
-  if(INUPT_CAPABILITY and OUTPUT_CAPABILITY){
+  if(INPUT_CAPABILITY and OUTPUT_CAPABILITY){
     Serial.println("Both devices will display randomly generated code and if they match authenticate pairing on both devices");
-  }else if(not INUPT_CAPABILITY and not OUTPUT_CAPABILITY){
+  }else if(not INPUT_CAPABILITY and not OUTPUT_CAPABILITY){
     Serial.println("Authenticate pairing on the other device. No PIN is used");
-  }else if(not INUPT_CAPABILITY and OUTPUT_CAPABILITY){
+  }else if(not INPUT_CAPABILITY and OUTPUT_CAPABILITY){
     Serial.println("Authenticate pairing on the other device. No PIN is used");
-  }else if(INUPT_CAPABILITY and not OUTPUT_CAPABILITY){
+  }else if(INPUT_CAPABILITY and not OUTPUT_CAPABILITY){
     Serial.println("After pairing is initiated you will be required to enter the passkey to the ESP32 device to authenticate\n > The Passkey will displayed on the other device");
   }
 }
diff --git a/libraries/BluetoothSerial/examples/bt_classic_device_discovery/bt_classic_device_discovery.ino b/libraries/BluetoothSerial/examples/bt_classic_device_discovery/bt_classic_device_discovery.ino
index 8d44f262174..b4ee741924d 100644
--- a/libraries/BluetoothSerial/examples/bt_classic_device_discovery/bt_classic_device_discovery.ino
+++ b/libraries/BluetoothSerial/examples/bt_classic_device_discovery/bt_classic_device_discovery.ino
@@ -1,17 +1,17 @@
 #include <BluetoothSerial.h>
 
 #if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
-#error Bluetooth is not enabled! Please run `make menuconfig` to and enable it
+  #error Bluetooth is not enabled! Please run `make menuconfig` to and enable it
 #endif
 
 #if !defined(CONFIG_BT_SPP_ENABLED)
-#error Serial Bluetooth not available or not enabled. It is only available for the ESP32 chip.
+  #error Serial Bluetooth not available or not enabled. It is only available for the ESP32 chip.
 #endif
 
 BluetoothSerial SerialBT;
 
 
-#define BT_DISCOVER_TIME	10000
+#define BT_DISCOVER_TIME 10000
 
 
 static bool btScanAsync = true;
@@ -19,7 +19,7 @@ static bool btScanSync = true;
 
 
 void btAdvertisedDeviceFound(BTAdvertisedDevice* pDevice) {
-	Serial.printf("Found a device asynchronously: %s\n", pDevice->toString().c_str());
+  Serial.printf("Found a device asynchronously: %s\n", pDevice->toString().c_str());
 }
 
 void setup() {
@@ -29,7 +29,7 @@ void setup() {
 
 
   if (btScanAsync) {
-    Serial.print("Starting discoverAsync...");
+    Serial.print("Starting asynchronous discovery... ");
     if (SerialBT.discoverAsync(btAdvertisedDeviceFound)) {
       Serial.println("Findings will be reported in \"btAdvertisedDeviceFound\"");
       delay(10000);
@@ -37,12 +37,12 @@ void setup() {
       SerialBT.discoverAsyncStop();
       Serial.println("stopped");
     } else {
-      Serial.println("Error on discoverAsync f.e. not workin after a \"connect\"");
+      Serial.println("Error on discoverAsync f.e. not working after a \"connect\"");
     }
   }
   
   if (btScanSync) {
-    Serial.println("Starting discover...");
+    Serial.println("Starting synchronous discovery... ");
     BTScanResults *pResults = SerialBT.discover(BT_DISCOVER_TIME);
     if (pResults)
       pResults->dump(&Serial);
diff --git a/libraries/BluetoothSerial/examples/bt_remove_paired_devices/bt_remove_paired_devices.ino b/libraries/BluetoothSerial/examples/bt_remove_paired_devices/bt_remove_paired_devices.ino
index 0d49fe46414..b2449d80ea5 100755
--- a/libraries/BluetoothSerial/examples/bt_remove_paired_devices/bt_remove_paired_devices.ino
+++ b/libraries/BluetoothSerial/examples/bt_remove_paired_devices/bt_remove_paired_devices.ino
@@ -1,91 +1,74 @@
-//This example code is in the Public Domain (or CC0 licensed, at your option.)
-//By Victor Tchistiak - 2019
+// This example code is in the Public Domain (or CC0 licensed, at your option.)
+// Originally by Victor Tchistiak - 2019
+// Rewritten with new API by Tomas Pilny - 2023
 //
-//This example demonstrates reading and removing paired devices stored on the ESP32 flash memory
-//Sometimes you may find your ESP32 device could not connect to the remote device despite
-//many successful connections earlier. This is most likely a result of client replacing your paired
-//device info with new one from other device. The BT clients store connection info for paired devices,
-//but it is limited to a few devices only. When new device pairs and number of stored devices is exceeded,
-//one of the previously paired devices would be replaced with new one.
-//The only remedy is to delete this saved bound device from your device flash memory
-//and pair with the other device again.
-//
-#include "esp_bt_main.h"
-#include "esp_bt_device.h"
-#include"esp_gap_bt_api.h"
-#include "esp_err.h"
+// This example demonstrates reading and removing paired devices stored on the ESP32 flash memory
+// Sometimes you may find your ESP32 device could not connect to the remote device despite
+// many successful connections earlier. This is most likely a result of client replacing your paired
+// device info with new one from other device. The BT clients store connection info for paired devices,
+// but it is limited to a few devices only. When new device pairs and number of stored devices is exceeded,
+// one of the previously paired devices would be replaced with new one.
+// The only remedy is to delete this saved bound device from your device flash memory
+// and pair with the other device again.
+
+#include "BluetoothSerial.h"
+//#include "esp_bt_device.h"
 
 #if !defined(CONFIG_BT_SPP_ENABLED)
-#error Serial Bluetooth not available or not enabled. It is only available for the ESP32 chip.
+  #error Serial Bluetooth not available or not enabled. It is only available for the ESP32 chip.
 #endif
 
-#define REMOVE_BONDED_DEVICES 0   // <- Set to 0 to view all bonded devices addresses, set to 1 to remove
-
+#define REMOVE_BONDED_DEVICES true  // <- Set to `false` to view all bonded devices addresses, set to `true` to remove
 #define PAIR_MAX_DEVICES 20
-uint8_t pairedDeviceBtAddr[PAIR_MAX_DEVICES][6];
-char bda_str[18];
+BluetoothSerial SerialBT;
 
-bool initBluetooth()
-{
-  if(!btStart()) {
-    Serial.println("Failed to initialize controller");
-    return false;
-  }
- 
-  if(esp_bluedroid_init() != ESP_OK) {
-    Serial.println("Failed to initialize bluedroid");
-    return false;
-  }
- 
-  if(esp_bluedroid_enable() != ESP_OK) {
-    Serial.println("Failed to enable bluedroid");
-    return false;
-  }
-  return true;
-}
-
-char *bda2str(const uint8_t* bda, char *str, size_t size)
-{
-  if (bda == NULL || str == NULL || size < 18) {
+char *bda2str(const uint8_t* bda, char *str, size_t size){
+  if (bda == NULL || str == NULL || size < 18){
     return NULL;
   }
   sprintf(str, "%02x:%02x:%02x:%02x:%02x:%02x",
           bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]);
   return str;
 }
- 
-void setup() {
+
+void setup(){
+  char bda_str[18];
+  uint8_t pairedDeviceBtAddr[PAIR_MAX_DEVICES][6];
   Serial.begin(115200);
- 
-  initBluetooth();
-  Serial.print("ESP32 bluetooth address: "); Serial.println(bda2str(esp_bt_dev_get_address(), bda_str, 18));
+
+  SerialBT.begin();
+  Serial.printf("ESP32 bluetooth address: %s\n", SerialBT.getBtAddressString().c_str());
+  // SerialBT.deleteAllBondedDevices(); // If you want just delete all, this is the way
   // Get the numbers of bonded/paired devices in the BT module
-  int count = esp_bt_gap_get_bond_device_num();
-  if(!count) {
-    Serial.println("No bonded device found.");
-  } else {
-    Serial.print("Bonded device count: "); Serial.println(count);
-    if(PAIR_MAX_DEVICES < count) {
-      count = PAIR_MAX_DEVICES; 
-      Serial.print("Reset bonded device count: "); Serial.println(count);
+  int count = SerialBT.getNumberOfBondedDevices();
+  if(!count){
+    Serial.println("No bonded devices found.");
+  }else{
+    Serial.printf("Bonded device count: %d\n", count);
+    if(PAIR_MAX_DEVICES < count){
+      count = PAIR_MAX_DEVICES;
+      Serial.printf("Reset %d bonded devices\n", count);
     }
-    esp_err_t tError =  esp_bt_gap_get_bond_device_list(&count, pairedDeviceBtAddr);
-    if(ESP_OK == tError) {
-      for(int i = 0; i < count; i++) {
-        Serial.print("Found bonded device # "); Serial.print(i); Serial.print(" -> ");
-        Serial.println(bda2str(pairedDeviceBtAddr[i], bda_str, 18));     
-        if(REMOVE_BONDED_DEVICES) {
-          esp_err_t tError = esp_bt_gap_remove_bond_device(pairedDeviceBtAddr[i]);
-          if(ESP_OK == tError) {
-            Serial.print("Removed bonded device # "); 
-          } else {
-            Serial.print("Failed to remove bonded device # ");
-          }
-          Serial.println(i);
+    count = SerialBT.getBondedDevices(count, pairedDeviceBtAddr);
+    char rmt_name[ESP_BT_GAP_MAX_BDNAME_LEN + 1];
+    if(count > 0){
+      for(int i = 0; i < count; i++){
+        SerialBT.requestRemoteName(pairedDeviceBtAddr[i]);
+        while(!SerialBT.readRemoteName(rmt_name)){
+          delay(1); // Wait for response with the device name
         }
-      }        
-    }
-  }
+        Serial.printf("Found bonded device #%d BDA:%s; Name:\"%s\"\n", i, bda2str(pairedDeviceBtAddr[i], bda_str, 18), rmt_name);
+        SerialBT.invalidateRemoteName(); // Allows waiting for next reading
+        if(REMOVE_BONDED_DEVICES){
+          if(SerialBT.deleteBondedDevice(pairedDeviceBtAddr[i])){
+            Serial.printf("Removed bonded device # %d\n", i);
+          }else{
+            Serial.printf("Failed to remove bonded device # %d", i);
+          } // if(ESP_OK == tError)
+        } // if(REMOVE_BONDED_DEVICES)
+      } // for(int i = 0; i < count; i++)
+    } // if(ESP_OK == tError)
+  } // if(!count)
 }
- 
-void loop() {}
+
+void loop() {}
\ No newline at end of file
diff --git a/libraries/BluetoothSerial/src/BluetoothSerial.cpp b/libraries/BluetoothSerial/src/BluetoothSerial.cpp
index 94bbf31a2d2..02fed2da7ac 100644
--- a/libraries/BluetoothSerial/src/BluetoothSerial.cpp
+++ b/libraries/BluetoothSerial/src/BluetoothSerial.cpp
@@ -60,6 +60,8 @@ static esp_bd_addr_t current_bd_addr;
 static ConfirmRequestCb confirm_request_callback = NULL;
 static KeyRequestCb key_request_callback = NULL;
 static AuthCompleteCb auth_complete_callback = NULL;
+static bool _rmt_name_valid = false;
+static uint8_t _rmt_name[ESP_BT_GAP_MAX_BDNAME_LEN + 1] = {0};
 
 #define INQ_LEN 0x10
 #define INQ_NUM_RSPS 20
@@ -575,6 +577,8 @@ static void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *pa
         case ESP_BT_GAP_READ_REMOTE_NAME_EVT:
             if (param->read_rmt_name.stat == ESP_BT_STATUS_SUCCESS ) {
                 log_i("ESP_BT_GAP_READ_REMOTE_NAME_EVT: %s", param->read_rmt_name.rmt_name);
+                memcpy(_rmt_name, param->read_rmt_name.rmt_name, ESP_BT_GAP_MAX_BDNAME_LEN + 1);
+                _rmt_name_valid = true;
             } else {
                 log_i("ESP_BT_GAP_READ_REMOTE_NAME_EVT: no success stat:%d", param->read_rmt_name.stat);
             }
@@ -1122,7 +1126,7 @@ bool BluetoothSerial::isReady(bool checkMaster, int timeout) {
 
 /**
  * @brief           RemoteName or address are not allowed to be set during discovery
- *                  (otherwhise it might connect automatically and stop discovery)
+ *                  (otherwise it might connect automatically and stop discovery)
  * @param[in]       timeoutMs can range from MIN_INQ_TIME to MAX_INQ_TIME
  * @return          in case of Error immediately Empty ScanResults.
  */
@@ -1146,11 +1150,11 @@ BTScanResults* BluetoothSerial::discover(int timeoutMs) {
 
 /**
  * @brief           RemoteName or address are not allowed to be set during discovery
- *                  (otherwhise it might connect automatically and stop discovery)
+ *                  (otherwise it might connect automatically and stop discovery)
  * @param[in]       cb called when a [b]new[/b] device has been discovered
  * @param[in]       timeoutMs can be 0 or range from MIN_INQ_TIME to MAX_INQ_TIME
  *
- * @return          Wheter start was successfull or problems with params
+ * @return          Whether start was successful or problems with params
  */
 bool BluetoothSerial::discoverAsync(BTAdvertisedDeviceCb cb, int timeoutMs) {
     scanResults.clear();
@@ -1173,7 +1177,7 @@ void BluetoothSerial::discoverAsyncStop() {
     advertisedDeviceCb = nullptr;
 }
 
-/** @brief      Clears scanresult entries */
+/** @brief      Clears scanResult entries */
 void BluetoothSerial::discoverClear() {
     scanResults.clear();
 }
@@ -1246,7 +1250,63 @@ String BluetoothSerial::getBtAddressString() {
     return getBtAddressObject().toString(true);
 }
 
-void BluetoothSerial::dropCache(){
+// Send a request to the remote device defined by the remoteAddress to send back its name.
+// The name will be read by background task and stored. It can be later read with radRemoteName()
+void BluetoothSerial::requestRemoteName(uint8_t remoteAddress[]){
+    if(isReady(false, READY_TIMEOUT)){
+        esp_bt_gap_read_remote_name(remoteAddress);
+    }
+}
+
+// If remote name is valid (was already received) this function will copy the name to the aprameter rmt_name
+// The buffer must have size at least ESP_BT_GAP_MAX_BDNAME_LEN + 1
+// If the name is valid the function will return true
+// If the name is not valid (was not read yet) returns false
+bool BluetoothSerial::readRemoteName(char rmt_name[ESP_BT_GAP_MAX_BDNAME_LEN + 1]){
+    if(_rmt_name_valid){
+        memcpy(rmt_name, _rmt_name, ESP_BT_GAP_MAX_BDNAME_LEN + 1);
+        return true;
+    }
+    return false;
+}
+
+// Set validity of remote name before reading name from different device
+void BluetoothSerial::invalidateRemoteName(){
+    _rmt_name_valid = false;
+}
+
+int BluetoothSerial::getNumberOfBondedDevices(){
+    return esp_bt_gap_get_bond_device_num();
+}
+
+// Accepts the maximum number of devices that can fit in given array dev_list.
+// Create you list this way: esp_bd_addr_t dev_list[dev_num];
+// Returns number of retrieved devices (on error returns 0)
+int BluetoothSerial::getBondedDevices(uint dev_num, esp_bd_addr_t *dev_list){
+    // typedef uint8_t esp_bd_addr_t[ESP_BD_ADDR_LEN]
+    if(dev_list == NULL){
+        log_e("Device list is NULL");
+        return 0;
+    }
+    if(dev_num == 0){
+        log_e("Device number must be larger than 0!");
+        return 0;
+    }
+    int _dev_num = dev_num;
+    esp_bt_gap_get_bond_device_list(&_dev_num, dev_list);
+    return _dev_num;
+}
+
+bool BluetoothSerial::deleteBondedDevice(uint8_t *remoteAddress){
+    esp_err_t ret = esp_bt_gap_remove_bond_device(remoteAddress);
+    if(ret == ESP_OK){
+        return true;
+    }else{
+        return false;
+    }
+}
+
+void BluetoothSerial::deleteAllBondedDevices(){
     if(!isReady(false, READY_TIMEOUT)){
         log_w("Attempted to drop cache for uninitialized driver. First call begin()");
         return;
diff --git a/libraries/BluetoothSerial/src/BluetoothSerial.h b/libraries/BluetoothSerial/src/BluetoothSerial.h
index 44c234eb63b..a53af307c31 100644
--- a/libraries/BluetoothSerial/src/BluetoothSerial.h
+++ b/libraries/BluetoothSerial/src/BluetoothSerial.h
@@ -92,7 +92,14 @@ class BluetoothSerial: public Stream
         void getBtAddress(uint8_t *mac);
         BTAddress getBtAddressObject();
         String getBtAddressString();
-        void dropCache();
+        //void dropCache(); // To be replaced
+        void requestRemoteName(uint8_t *remoteAddress);
+        bool readRemoteName(char rmt_name[ESP_BT_GAP_MAX_BDNAME_LEN + 1]);
+        void invalidateRemoteName();
+        int getNumberOfBondedDevices();
+        int getBondedDevices(uint dev_num, esp_bd_addr_t *dev_list);
+        bool deleteBondedDevice(uint8_t *remoteAddress);
+        void deleteAllBondedDevices();
     private:
         String local_name;
         int timeoutTicks=0;

From 7703ebeeceefc4235c926fe31703800fabdafc01 Mon Sep 17 00:00:00 2001
From: Tomas Pilny <tomas.pilny@espressif.com>
Date: Fri, 4 Aug 2023 13:21:59 +0200
Subject: [PATCH 09/14] Added SPP event

---
 .../examples/DiscoverConnect/DiscoverConnect.ino            | 5 ++---
 .../BluetoothSerial/examples/GetLocalMAC/GetLocalMAC.ino    | 4 ++--
 libraries/BluetoothSerial/src/BluetoothSerial.cpp           | 6 +++++-
 3 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/libraries/BluetoothSerial/examples/DiscoverConnect/DiscoverConnect.ino b/libraries/BluetoothSerial/examples/DiscoverConnect/DiscoverConnect.ino
index 168ea9d19c4..e5d5e676c91 100644
--- a/libraries/BluetoothSerial/examples/DiscoverConnect/DiscoverConnect.ino
+++ b/libraries/BluetoothSerial/examples/DiscoverConnect/DiscoverConnect.ino
@@ -19,16 +19,15 @@
 #include <BluetoothSerial.h>
 
 #if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
-#error Bluetooth is not enabled! Please run `make menuconfig` to and enable it
+  #error Bluetooth is not enabled! Please run `make menuconfig` to and enable it
 #endif
 
 #if !defined(CONFIG_BT_SPP_ENABLED)
-#error Serial Bluetooth not available or not enabled. It is only available for the ESP32 chip.
+  #error Serial Bluetooth not available or not enabled. It is only available for the ESP32 chip.
 #endif
 
 BluetoothSerial SerialBT;
 
-
 #define BT_DISCOVER_TIME  10000
 esp_spp_sec_t sec_mask=ESP_SPP_SEC_NONE; // or ESP_SPP_SEC_ENCRYPT|ESP_SPP_SEC_AUTHENTICATE to request pincode confirmation
 esp_spp_role_t role=ESP_SPP_ROLE_SLAVE; // or ESP_SPP_ROLE_MASTER
diff --git a/libraries/BluetoothSerial/examples/GetLocalMAC/GetLocalMAC.ino b/libraries/BluetoothSerial/examples/GetLocalMAC/GetLocalMAC.ino
index a3ca6b026b6..2930067bf5d 100644
--- a/libraries/BluetoothSerial/examples/GetLocalMAC/GetLocalMAC.ino
+++ b/libraries/BluetoothSerial/examples/GetLocalMAC/GetLocalMAC.ino
@@ -6,11 +6,11 @@
 String device_name = "ESP32-example";
 
 #if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
-#error Bluetooth is not enabled! Please run `make menuconfig` to and enable it
+  #error Bluetooth is not enabled! Please run `make menuconfig` to and enable it
 #endif
 
 #if !defined(CONFIG_BT_SPP_ENABLED)
-#error Serial Bluetooth not available or not enabled. It is only available for the ESP32 chip.
+  #error Serial Bluetooth not available or not enabled. It is only available for the ESP32 chip.
 #endif
 
 BluetoothSerial SerialBT;
diff --git a/libraries/BluetoothSerial/src/BluetoothSerial.cpp b/libraries/BluetoothSerial/src/BluetoothSerial.cpp
index 02fed2da7ac..491fed44656 100644
--- a/libraries/BluetoothSerial/src/BluetoothSerial.cpp
+++ b/libraries/BluetoothSerial/src/BluetoothSerial.cpp
@@ -259,6 +259,10 @@ static void esp_spp_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param)
         xEventGroupSetBits(_spp_event_group, SPP_RUNNING);
         break;
 
+    case ESP_SPP_UNINIT_EVT:
+        log_i("ESP_SPP_UNINIT_EVT: SPP is deinitialized");
+        break;
+
     case ESP_SPP_SRV_OPEN_EVT://Server connection open
         if (param->srv_open.status == ESP_SPP_SUCCESS) {
             log_i("ESP_SPP_SRV_OPEN_EVT: %u", _spp_client);
@@ -392,7 +396,7 @@ static void esp_spp_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param)
         break;
 
     default:
-        log_i("ESP_SPP_* event unhandled %d", event);
+        log_i("ESP_SPP_* event #%d unhandled", event);
         break;
     }
     if(custom_spp_callback)(*custom_spp_callback)(event, param);

From b5a09c423f697b25b3b80e5d5ad95b292e3aa606 Mon Sep 17 00:00:00 2001
From: Tomas Pilny <tomas.pilny@espressif.com>
Date: Fri, 4 Aug 2023 14:07:32 +0200
Subject: [PATCH 10/14] Reordered event to match enum declaration; added
 missing events; added comments

---
 .../BluetoothSerial/src/BluetoothSerial.cpp   | 244 +++++++++---------
 1 file changed, 128 insertions(+), 116 deletions(-)

diff --git a/libraries/BluetoothSerial/src/BluetoothSerial.cpp b/libraries/BluetoothSerial/src/BluetoothSerial.cpp
index 491fed44656..46a6d829754 100644
--- a/libraries/BluetoothSerial/src/BluetoothSerial.cpp
+++ b/libraries/BluetoothSerial/src/BluetoothSerial.cpp
@@ -245,7 +245,7 @@ static void esp_spp_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param)
 {
     switch (event)
     {
-    case ESP_SPP_INIT_EVT:
+    case ESP_SPP_INIT_EVT: // Enum 0 - When SPP is initialized
         log_i("ESP_SPP_INIT_EVT");
 #ifdef ESP_IDF_VERSION_MAJOR
         esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE);
@@ -259,28 +259,58 @@ static void esp_spp_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param)
         xEventGroupSetBits(_spp_event_group, SPP_RUNNING);
         break;
 
-    case ESP_SPP_UNINIT_EVT:
+    case ESP_SPP_UNINIT_EVT: // Enum 1 - When SPP is deinitialized
         log_i("ESP_SPP_UNINIT_EVT: SPP is deinitialized");
         break;
 
-    case ESP_SPP_SRV_OPEN_EVT://Server connection open
-        if (param->srv_open.status == ESP_SPP_SUCCESS) {
-            log_i("ESP_SPP_SRV_OPEN_EVT: %u", _spp_client);
-            if (!_spp_client){
-                _spp_client = param->srv_open.handle;
-                _spp_tx_buffer_len = 0;
+    case ESP_SPP_DISCOVERY_COMP_EVT: // Enum 8 - When SDP discovery complete
+        log_i("ESP_SPP_DISCOVERY_COMP_EVT num=%d", param->disc_comp.scn_num);
+        if (param->disc_comp.status == ESP_SPP_SUCCESS) {
+            for(int i=0; i < param->disc_comp.scn_num; i++) {
+                log_d("ESP_SPP_DISCOVERY_COMP_EVT: spp [%d] channel: %d service name:%s", i, param->disc_comp.scn[i], param->disc_comp.service_name[0]);
+            }
+            if(_doConnect) {
+                if(param->disc_comp.scn_num > 0) {
+#if (ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_INFO)
+                    char bda_str[18];
+                    log_i("ESP_SPP_DISCOVERY_COMP_EVT: spp connect to remote %s channel %d",
+                        bda2str(_peer_bd_addr, bda_str, sizeof(bda_str)),
+                        param->disc_comp.scn[0]);
+#endif
+                    xEventGroupClearBits(_spp_event_group, SPP_CLOSED);
+                    if(esp_spp_connect(_sec_mask, _role, param->disc_comp.scn[0], _peer_bd_addr) != ESP_OK) {
+                        log_e("ESP_SPP_DISCOVERY_COMP_EVT connect failed");
+                        xEventGroupSetBits(_spp_event_group, SPP_CLOSED);
+                    }
+                } else {
+                    log_e("ESP_SPP_DISCOVERY_COMP_EVT remote doesn't offer an SPP channel");
+                    xEventGroupSetBits(_spp_event_group, SPP_CLOSED);
+                }
             } else {
-                secondConnectionAttempt = true;
-                esp_spp_disconnect(param->srv_open.handle);
+                for(int i=0; i < param->disc_comp.scn_num; i++) {
+                    sdpRecords[param->disc_comp.scn[i]] = param->disc_comp.service_name[0];
+                }
             }
-            xEventGroupClearBits(_spp_event_group, SPP_DISCONNECTED);
-            xEventGroupSetBits(_spp_event_group, SPP_CONNECTED);
         } else {
-            log_e("ESP_SPP_SRV_OPEN_EVT Failed!, status:%d", param->srv_open.status);
+            log_e("ESP_SPP_DISCOVERY_COMP_EVT failed!, status:%d", param->disc_comp.status);
         }
+        xEventGroupSetBits(_bt_event_group, BT_SDP_COMPLETED);
         break;
 
-    case ESP_SPP_CLOSE_EVT://Client connection closed
+    case ESP_SPP_OPEN_EVT: // Enum 26 - When SPP Client connection open
+        log_i("ESP_SPP_OPEN_EVT");
+        if (!_spp_client){
+                _spp_client = param->open.handle;
+        } else {
+            secondConnectionAttempt = true;
+            esp_spp_disconnect(param->open.handle);
+        }
+        xEventGroupClearBits(_spp_event_group, SPP_DISCONNECTED);
+        xEventGroupSetBits(_spp_event_group, SPP_CONNECTED);
+        xEventGroupSetBits(_spp_event_group, SPP_CONGESTED);
+        break;
+
+    case ESP_SPP_CLOSE_EVT: // Enum 27 - When SPP connection closed
         if ((param->close.async == false && param->close.status == ESP_SPP_SUCCESS) || param->close.async) {
             log_i("ESP_SPP_CLOSE_EVT status:%d handle:%d close_by_remote:%d attempt %u", param->close.status,
                  param->close.handle, param->close.async, secondConnectionAttempt);
@@ -292,34 +322,25 @@ static void esp_spp_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param)
                 xEventGroupSetBits(_spp_event_group, SPP_CONGESTED);
                 xEventGroupSetBits(_spp_event_group, SPP_CLOSED);
                 xEventGroupClearBits(_spp_event_group, SPP_CONNECTED);
-            }        
+            }
         } else {
             log_e("ESP_SPP_CLOSE_EVT failed!, status:%d", param->close.status);
         }
         break;
 
-    case ESP_SPP_CONG_EVT://connection congestion status changed
-        if(param->cong.cong){
-            xEventGroupClearBits(_spp_event_group, SPP_CONGESTED);
-        } else {
-            xEventGroupSetBits(_spp_event_group, SPP_CONGESTED);
-        }
-        log_v("ESP_SPP_CONG_EVT: %s", param->cong.cong?"CONGESTED":"FREE");
+    case ESP_SPP_START_EVT: // Enum 28 - When SPP server started
+        log_i("ESP_SPP_START_EVT");
         break;
 
-    case ESP_SPP_WRITE_EVT://write operation completed
-        if (param->write.status == ESP_SPP_SUCCESS) {
-            if(param->write.cong){
-                xEventGroupClearBits(_spp_event_group, SPP_CONGESTED);
-            }
-            log_v("ESP_SPP_WRITE_EVT: %u %s", param->write.len, param->write.cong?"CONGESTED":"");
+    case ESP_SPP_CL_INIT_EVT: // Enum 29 - When SPP client initiated a connection
+        if (param->cl_init.status == ESP_SPP_SUCCESS) {
+            log_i("ESP_SPP_CL_INIT_EVT handle:%d sec_id:%d", param->cl_init.handle, param->cl_init.sec_id);
         } else {
-            log_e("ESP_SPP_WRITE_EVT failed!, status:%d", param->write.status);
+            log_i("ESP_SPP_CL_INIT_EVT status:%d", param->cl_init.status);
         }
-        xSemaphoreGive(_spp_tx_done);//we can try to send another packet
         break;
 
-    case ESP_SPP_DATA_IND_EVT://connection received data
+    case ESP_SPP_DATA_IND_EVT: // Enum 30 - When SPP connection received data, only for ESP_SPP_MODE_CB
         log_v("ESP_SPP_DATA_IND_EVT len=%d handle=%d", param->data_ind.len, param->data_ind.handle);
         //esp_log_buffer_hex("",param->data_ind.data,param->data_ind.len); //for low level debug
         //ets_printf("r:%u\n", param->data_ind.len);
@@ -336,63 +357,54 @@ static void esp_spp_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param)
         }
         break;
 
-    case ESP_SPP_DISCOVERY_COMP_EVT://discovery complete
-        log_i("ESP_SPP_DISCOVERY_COMP_EVT num=%d", param->disc_comp.scn_num);
-        if (param->disc_comp.status == ESP_SPP_SUCCESS) {
-            for(int i=0; i < param->disc_comp.scn_num; i++) {
-                log_d("ESP_SPP_DISCOVERY_COMP_EVT: spp [%d] channel: %d service name:%s", i, param->disc_comp.scn[i], param->disc_comp.service_name[0]);
-            }
-            if(_doConnect) {
-                if(param->disc_comp.scn_num > 0) {
-#if (ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_INFO)
-                    char bda_str[18];
-                    log_i("ESP_SPP_DISCOVERY_COMP_EVT: spp connect to remote %s channel %d",
-                        bda2str(_peer_bd_addr, bda_str, sizeof(bda_str)),
-                        param->disc_comp.scn[0]);
-#endif
-                    xEventGroupClearBits(_spp_event_group, SPP_CLOSED);
-                    if(esp_spp_connect(_sec_mask, _role, param->disc_comp.scn[0], _peer_bd_addr) != ESP_OK) {
-                        log_e("ESP_SPP_DISCOVERY_COMP_EVT connect failed");
-                        xEventGroupSetBits(_spp_event_group, SPP_CLOSED);
-                    }
-                } else {
-                    log_e("ESP_SPP_DISCOVERY_COMP_EVT remote doesn't offer an SPP channel");
-                    xEventGroupSetBits(_spp_event_group, SPP_CLOSED);
-                }
-            } else {
-                for(int i=0; i < param->disc_comp.scn_num; i++) {
-                    sdpRecords[param->disc_comp.scn[i]] = param->disc_comp.service_name[0];
-                }
+    case ESP_SPP_CONG_EVT: // Enum 31 - When SPP connection congestion status changed, only for ESP_SPP_MODE_CB
+        if(param->cong.cong){
+            xEventGroupClearBits(_spp_event_group, SPP_CONGESTED);
+        } else {
+            xEventGroupSetBits(_spp_event_group, SPP_CONGESTED);
+        }
+        log_v("ESP_SPP_CONG_EVT: %s", param->cong.cong?"CONGESTED":"FREE");
+        break;
+
+    case ESP_SPP_WRITE_EVT: // Enum 33 - When SPP write operation completes, only for ESP_SPP_MODE_CB
+        if (param->write.status == ESP_SPP_SUCCESS) {
+            if(param->write.cong){
+                xEventGroupClearBits(_spp_event_group, SPP_CONGESTED);
             }
+            log_v("ESP_SPP_WRITE_EVT: %u %s", param->write.len, param->write.cong?"CONGESTED":"");
         } else {
-            log_e("ESP_SPP_DISCOVERY_COMP_EVT failed!, status:%d", param->disc_comp.status);
+            log_e("ESP_SPP_WRITE_EVT failed!, status:%d", param->write.status);
         }
-        xEventGroupSetBits(_bt_event_group, BT_SDP_COMPLETED);
+        xSemaphoreGive(_spp_tx_done);//we can try to send another packet
         break;
 
-    case ESP_SPP_OPEN_EVT://Client connection open
-        log_i("ESP_SPP_OPEN_EVT");
-        if (!_spp_client){
-                _spp_client = param->open.handle;
+    case ESP_SPP_SRV_OPEN_EVT: // Enum 34 - When SPP Server connection open
+        if (param->srv_open.status == ESP_SPP_SUCCESS) {
+            log_i("ESP_SPP_SRV_OPEN_EVT: %u", _spp_client);
+            if (!_spp_client){
+                _spp_client = param->srv_open.handle;
+                _spp_tx_buffer_len = 0;
+            } else {
+                secondConnectionAttempt = true;
+                esp_spp_disconnect(param->srv_open.handle);
+            }
+            xEventGroupClearBits(_spp_event_group, SPP_DISCONNECTED);
+            xEventGroupSetBits(_spp_event_group, SPP_CONNECTED);
         } else {
-            secondConnectionAttempt = true;
-            esp_spp_disconnect(param->open.handle);
+            log_e("ESP_SPP_SRV_OPEN_EVT Failed!, status:%d", param->srv_open.status);
         }
-        xEventGroupClearBits(_spp_event_group, SPP_DISCONNECTED);
-        xEventGroupSetBits(_spp_event_group, SPP_CONNECTED);
-        xEventGroupSetBits(_spp_event_group, SPP_CONGESTED);
         break;
 
-    case ESP_SPP_START_EVT://server started
-        log_i("ESP_SPP_START_EVT");
+    case ESP_SPP_SRV_STOP_EVT: // Enum 35 - When SPP server stopped
+        log_i("ESP_SPP_SRV_STOP_EVT");
         break;
 
-    case ESP_SPP_CL_INIT_EVT://client initiated a connection
-        if (param->cl_init.status == ESP_SPP_SUCCESS) {
-            log_i("ESP_SPP_CL_INIT_EVT handle:%d sec_id:%d", param->cl_init.handle, param->cl_init.sec_id);
-        } else {
-            log_i("ESP_SPP_CL_INIT_EVT status:%d", param->cl_init.status);
-        }
+    case ESP_SPP_VFS_REGISTER_EVT: // Enum 36 - When SPP VFS register
+        log_i("ESP_SPP_VFS_REGISTER_EVT");
+        break;
+
+    case ESP_SPP_VFS_UNREGISTER_EVT: // Enum 37 - When SPP VFS unregister
+        log_i("ESP_SPP_VFS_UNREGISTER_EVT");
         break;
 
     default:
@@ -406,10 +418,11 @@ void BluetoothSerial::onData(BluetoothSerialDataCb cb){
     custom_data_callback = cb;
 }
 
+
 static void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param)
 {
     switch(event){
-        case ESP_BT_GAP_DISC_RES_EVT: {
+        case ESP_BT_GAP_DISC_RES_EVT: { // Enum 0 - Device discovery result event
             log_i("ESP_BT_GAP_DISC_RES_EVT properties=%d", param->disc_res.num_prop);
 #if (ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_INFO)
             char bda_str[18];
@@ -420,21 +433,7 @@ static void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *pa
             char peer_bdname[ESP_BT_GAP_MAX_BDNAME_LEN + 1];
             for (int i = 0; i < param->disc_res.num_prop; i++) {
                 switch(param->disc_res.prop[i].type) {
-                    case ESP_BT_GAP_DEV_PROP_EIR:  
-                        if (get_name_from_eir((uint8_t*)param->disc_res.prop[i].val, peer_bdname, &peer_bdname_len)) {
-                            log_i("ESP_BT_GAP_DISC_RES_EVT : EIR : %s : %d", peer_bdname, peer_bdname_len);
-                            if (strlen(_remote_name) == peer_bdname_len
-                                && strncmp(peer_bdname, _remote_name, peer_bdname_len) == 0) {
-                                log_v("ESP_BT_GAP_DISC_RES_EVT : SPP_START_DISCOVERY_EIR : %s", peer_bdname, peer_bdname_len);
-                                _isRemoteAddressSet = true;
-                                memcpy(_peer_bd_addr, param->disc_res.bda, ESP_BD_ADDR_LEN);
-                                esp_bt_gap_cancel_discovery();
-                                esp_spp_start_discovery(_peer_bd_addr);
-                            }
-                        }
-                        break;
-
-                    case ESP_BT_GAP_DEV_PROP_BDNAME:
+                    case ESP_BT_GAP_DEV_PROP_BDNAME: // Enum 1 - Bluetooth device name, value type is int8_t []
                         peer_bdname_len = param->disc_res.prop[i].len;
                         memcpy(peer_bdname, param->disc_res.prop[i].val, peer_bdname_len);
                         peer_bdname_len--; // len includes 0 terminator
@@ -446,10 +445,10 @@ static void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *pa
                             memcpy(_peer_bd_addr, param->disc_res.bda, ESP_BD_ADDR_LEN);
                             esp_bt_gap_cancel_discovery();
                             esp_spp_start_discovery(_peer_bd_addr);
-                        } 
+                        }
                         break;
 
-                    case ESP_BT_GAP_DEV_PROP_COD:
+                    case ESP_BT_GAP_DEV_PROP_COD: // Enum 2 - Class of Device, value type is uint32_t
                         if (param->disc_res.prop[i].len <= sizeof(int)) {
                             uint32_t cod = 0;
                             memcpy(&cod, param->disc_res.prop[i].val, param->disc_res.prop[i].len);
@@ -460,7 +459,7 @@ static void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *pa
                         }
                         break;
 
-                    case ESP_BT_GAP_DEV_PROP_RSSI:
+                    case ESP_BT_GAP_DEV_PROP_RSSI: // Enum 3 - Received Signal strength Indication, value type is int8_t, ranging from -128 to 127
                         if (param->disc_res.prop[i].len <= sizeof(int)) {
                             uint8_t rssi = 0;
                             memcpy(&rssi, param->disc_res.prop[i].val, param->disc_res.prop[i].len);
@@ -470,7 +469,21 @@ static void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *pa
                             log_d("ESP_BT_GAP_DEV_PROP_RSSI invalid RSSI: Value size larger than integer");
                         }
                         break;
-                        
+
+                    case ESP_BT_GAP_DEV_PROP_EIR: // Enum 4 - Extended Inquiry Response, value type is uint8_t []
+                        if (get_name_from_eir((uint8_t*)param->disc_res.prop[i].val, peer_bdname, &peer_bdname_len)) {
+                            log_i("ESP_BT_GAP_DISC_RES_EVT : EIR : %s : %d", peer_bdname, peer_bdname_len);
+                            if (strlen(_remote_name) == peer_bdname_len
+                                && strncmp(peer_bdname, _remote_name, peer_bdname_len) == 0) {
+                                log_v("ESP_BT_GAP_DISC_RES_EVT : SPP_START_DISCOVERY_EIR : %s", peer_bdname, peer_bdname_len);
+                                _isRemoteAddressSet = true;
+                                memcpy(_peer_bd_addr, param->disc_res.bda, ESP_BD_ADDR_LEN);
+                                esp_bt_gap_cancel_discovery();
+                                esp_spp_start_discovery(_peer_bd_addr);
+                            }
+                        }
+                        break;
+
                     default:
                         log_i("ESP_BT_GAP_DISC_RES_EVT unknown property [%d]:type:%d", i, param->disc_res.prop[i].type);
                         break;
@@ -488,7 +501,7 @@ static void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *pa
         }
         break;
 
-        case ESP_BT_GAP_DISC_STATE_CHANGED_EVT:
+        case ESP_BT_GAP_DISC_STATE_CHANGED_EVT: // Enum 1 - Discovery state changed event
             if (param->disc_st_chg.state == ESP_BT_GAP_DISCOVERY_STOPPED) {
                 log_i("ESP_BT_GAP_DISC_STATE_CHANGED_EVT stopped");
                 xEventGroupClearBits(_bt_event_group, BT_DISCOVERY_RUNNING);
@@ -500,15 +513,15 @@ static void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *pa
             }
             break;
 
-        case ESP_BT_GAP_RMT_SRVCS_EVT:
+        case ESP_BT_GAP_RMT_SRVCS_EVT: // Enum 2 - Get remote services event
             log_i( "ESP_BT_GAP_RMT_SRVCS_EVT: status = %d, num_uuids = %d", param->rmt_srvcs.stat, param->rmt_srvcs.num_uuids);
             break;
 
-        case ESP_BT_GAP_RMT_SRVC_REC_EVT:
+        case ESP_BT_GAP_RMT_SRVC_REC_EVT: // Enum 3 - Get remote service record event
             log_i("ESP_BT_GAP_RMT_SRVC_REC_EVT: status = %d", param->rmt_srvc_rec.stat);
             break;
 
-        case ESP_BT_GAP_AUTH_CMPL_EVT:
+        case ESP_BT_GAP_AUTH_CMPL_EVT: // Enum 4 - Authentication complete event
             if (param->auth_cmpl.stat == ESP_BT_STATUS_SUCCESS) {
                 log_v("authentication success: %s", param->auth_cmpl.device_name);
                 if (auth_complete_callback) {
@@ -521,8 +534,7 @@ static void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *pa
                 }
             }
             break;
-
-        case ESP_BT_GAP_PIN_REQ_EVT:
+        case ESP_BT_GAP_PIN_REQ_EVT: // Enum 5 - Legacy Pairing Pin code request
             // default pairing pins
             log_i("ESP_BT_GAP_PIN_REQ_EVT min_16_digit:%d", param->pin_req.min_16_digit);
             if (param->pin_req.min_16_digit) {
@@ -538,7 +550,7 @@ static void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *pa
             }
             break;
        
-        case ESP_BT_GAP_CFM_REQ_EVT:
+        case ESP_BT_GAP_CFM_REQ_EVT: // Enum 6 - Security Simple Pairing User Confirmation request.
             log_i("ESP_BT_GAP_CFM_REQ_EVT Please compare the numeric value: %d", param->cfm_req.num_val);
             if (confirm_request_callback) {
                 memcpy(current_bd_addr, param->cfm_req.bda, sizeof(esp_bd_addr_t));
@@ -550,11 +562,11 @@ static void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *pa
             }
             break;
 
-        case ESP_BT_GAP_KEY_NOTIF_EVT:
+        case ESP_BT_GAP_KEY_NOTIF_EVT: // Enum 7 - Security Simple Pairing Passkey Notification
             log_i("ESP_BT_GAP_KEY_NOTIF_EVT passkey:%d", param->key_notif.passkey);
             break;
 
-        case ESP_BT_GAP_KEY_REQ_EVT:
+        case ESP_BT_GAP_KEY_REQ_EVT: // Enum 8 - Security Simple Pairing Passkey request
             log_i("ESP_BT_GAP_KEY_REQ_EVT Please enter passkey!");
             if (key_request_callback) {
                 memcpy(current_bd_addr, param->cfm_req.bda, sizeof(esp_bd_addr_t));
@@ -566,19 +578,18 @@ static void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *pa
             }
             break;
 
-        case ESP_BT_GAP_READ_RSSI_DELTA_EVT:
+        case ESP_BT_GAP_READ_RSSI_DELTA_EVT: // Enum 9 - Read rssi event
             log_i("ESP_BT_GAP_READ_RSSI_DELTA_EVT Read rssi event");
             break;
-
-        case ESP_BT_GAP_CONFIG_EIR_DATA_EVT:
+        case ESP_BT_GAP_CONFIG_EIR_DATA_EVT: // Enum 10 - Config EIR data event
             log_i("ESP_BT_GAP_CONFIG_EIR_DATA_EVT: stat:%d num:%d", param->config_eir_data.stat, param->config_eir_data.eir_type_num);
             break;
 
-        case ESP_BT_GAP_SET_AFH_CHANNELS_EVT:
+        case ESP_BT_GAP_SET_AFH_CHANNELS_EVT: // Enum 11 - Set AFH channels event
             log_i("ESP_BT_GAP_SET_AFH_CHANNELS_EVT Set AFH channels event");
             break;
 
-        case ESP_BT_GAP_READ_REMOTE_NAME_EVT:
+        case ESP_BT_GAP_READ_REMOTE_NAME_EVT: // Enum 12 - Read Remote Name event
             if (param->read_rmt_name.stat == ESP_BT_STATUS_SUCCESS ) {
                 log_i("ESP_BT_GAP_READ_REMOTE_NAME_EVT: %s", param->read_rmt_name.rmt_name);
                 memcpy(_rmt_name, param->read_rmt_name.rmt_name, ESP_BT_GAP_MAX_BDNAME_LEN + 1);
@@ -588,23 +599,24 @@ static void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *pa
             }
             break;
 
-        case ESP_BT_GAP_MODE_CHG_EVT:
+
+        case ESP_BT_GAP_MODE_CHG_EVT: // Enum 13
             log_i("ESP_BT_GAP_MODE_CHG_EVT: mode: %d", param->mode_chg.mode);
             break;
 
-        case ESP_BT_GAP_REMOVE_BOND_DEV_COMPLETE_EVT:
+        case ESP_BT_GAP_REMOVE_BOND_DEV_COMPLETE_EVT: // Enum - 14 remove bond device complete event
             log_i("ESP_BT_GAP_REMOVE_BOND_DEV_COMPLETE_EVT remove bond device complete event");
             break;
 
-        case ESP_BT_GAP_QOS_CMPL_EVT:
+        case ESP_BT_GAP_QOS_CMPL_EVT: // Enum 15 - QOS complete event
             log_i("ESP_BT_GAP_QOS_CMPL_EVT QOS complete event");
             break;
 
-        case ESP_BT_GAP_ACL_CONN_CMPL_STAT_EVT:
+        case ESP_BT_GAP_ACL_CONN_CMPL_STAT_EVT: // Enum 16 - ACL connection complete status event
             log_i("ESP_BT_GAP_ACL_CONN_CMPL_STAT_EVT ACL connection complete status event");
             break;
 
-        case ESP_BT_GAP_ACL_DISCONN_CMPL_STAT_EVT:
+        case ESP_BT_GAP_ACL_DISCONN_CMPL_STAT_EVT: // Enum 17 - ACL disconnection complete status event
             log_i("ESP_BT_GAP_ACL_DISCONN_CMPL_STAT_EVT ACL disconnection complete status event: reason %d, handle %d", param->acl_disconn_cmpl_stat.reason, param->acl_disconn_cmpl_stat.handle);
             break;
 

From 672395f7df326bc0208c4eaf69179a571563b8a8 Mon Sep 17 00:00:00 2001
From: Tomas Pilny <tomas.pilny@espressif.com>
Date: Wed, 9 Aug 2023 14:05:20 +0200
Subject: [PATCH 11/14] Re-implemented legacy pairing support

---
 libraries/BluetoothSerial/README.md           | 17 ++++-
 .../SerialToSerialBT_Legacy/.skip.esp32c3     |  0
 .../SerialToSerialBT_Legacy/.skip.esp32c6     |  0
 .../SerialToSerialBT_Legacy/.skip.esp32h2     |  0
 .../SerialToSerialBT_Legacy/.skip.esp32s2     |  0
 .../SerialToSerialBT_Legacy/.skip.esp32s3     |  0
 .../SerialToSerialBT_Legacy.ino               | 66 +++++++++++++++++++
 .../SerialToSerialBT_SSP.ino                  |  1 -
 libraries/BluetoothSerial/src/BTScan.h        | 16 ++---
 .../BluetoothSerial/src/BluetoothSerial.cpp   | 53 ++++++++++-----
 .../BluetoothSerial/src/BluetoothSerial.h     |  8 +++
 11 files changed, 133 insertions(+), 28 deletions(-)
 create mode 100644 libraries/BluetoothSerial/examples/SerialToSerialBT_Legacy/.skip.esp32c3
 create mode 100644 libraries/BluetoothSerial/examples/SerialToSerialBT_Legacy/.skip.esp32c6
 create mode 100644 libraries/BluetoothSerial/examples/SerialToSerialBT_Legacy/.skip.esp32h2
 create mode 100644 libraries/BluetoothSerial/examples/SerialToSerialBT_Legacy/.skip.esp32s2
 create mode 100644 libraries/BluetoothSerial/examples/SerialToSerialBT_Legacy/.skip.esp32s3
 create mode 100644 libraries/BluetoothSerial/examples/SerialToSerialBT_Legacy/SerialToSerialBT_Legacy.ino

diff --git a/libraries/BluetoothSerial/README.md b/libraries/BluetoothSerial/README.md
index 4bcf353ba4e..14348519b51 100644
--- a/libraries/BluetoothSerial/README.md
+++ b/libraries/BluetoothSerial/README.md
@@ -34,7 +34,11 @@ Using 3rd party Serial BT module will require to study the documentation of the
 
 ### Pairing options
 
-There are two major options - with and without Secure Simple Pairing (SSP).
+There are two easy options and one difficult.
+
+The easy options can be used as usual. These offer pairing with and without Secure Simple Pairing (SSP).
+
+The difficult option offers legacy pairing (using fixed PIN) however this must be compiled with Arduino as an IDF component with disabled sdkconfig option `CONFIG_BT_SSP_ENABLED`.
 
 #### Without SSP
 
@@ -63,5 +67,12 @@ Both options must be called before `begin()` or if it is called after `begin()`
 * **inputCapability=false and outputCapability=true**
     * Only the other device authenticates pairing without any pin.
 * **inputCapability=true and outputCapability=false**
-    * User will be required to input the passkey to the ESP32 device to authenticate.
-    * This must be implemented by registering callback via `onKeyRequest()` and in this callback the entered passkey will be responded via `respondPasskey(passkey)`
\ No newline at end of file
+    * The user will be required to input the passkey to the ESP32 device to authenticate.
+    * This must be implemented by registering a callback via `onKeyRequest`()` and in this callback the entered passkey will be responded via `respondPasskey(passkey)`
+
+### Legacy Pairing (IDF component)
+
+To use Legacy pairing you will have to use [Arduino as an IDF component](https://espressif-docs.readthedocs-hosted.com/projects/arduino-esp32/en/latest/esp-idf_component.html) and disable option `CONFIG_BT_SSP_ENABLED`.
+Please refer to the documentation on how to setup Arduino as an IDF component and when you are done, run `idf.py menuconfig` navigate to `Component Config -> Bluetooth -> Bluedroid -> [ ] Secure Simple Pairing` and disable it.
+While in the menuconfig you will also need to change partition scheme `Partition Table -> Partition Table -> (X) Single Factory app (large), no OTA`.
+After these changes save & quit menuconfig a you are ready to go: `idf.py  monitor flash`.
\ No newline at end of file
diff --git a/libraries/BluetoothSerial/examples/SerialToSerialBT_Legacy/.skip.esp32c3 b/libraries/BluetoothSerial/examples/SerialToSerialBT_Legacy/.skip.esp32c3
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/libraries/BluetoothSerial/examples/SerialToSerialBT_Legacy/.skip.esp32c6 b/libraries/BluetoothSerial/examples/SerialToSerialBT_Legacy/.skip.esp32c6
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/libraries/BluetoothSerial/examples/SerialToSerialBT_Legacy/.skip.esp32h2 b/libraries/BluetoothSerial/examples/SerialToSerialBT_Legacy/.skip.esp32h2
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/libraries/BluetoothSerial/examples/SerialToSerialBT_Legacy/.skip.esp32s2 b/libraries/BluetoothSerial/examples/SerialToSerialBT_Legacy/.skip.esp32s2
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/libraries/BluetoothSerial/examples/SerialToSerialBT_Legacy/.skip.esp32s3 b/libraries/BluetoothSerial/examples/SerialToSerialBT_Legacy/.skip.esp32s3
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/libraries/BluetoothSerial/examples/SerialToSerialBT_Legacy/SerialToSerialBT_Legacy.ino b/libraries/BluetoothSerial/examples/SerialToSerialBT_Legacy/SerialToSerialBT_Legacy.ino
new file mode 100644
index 00000000000..27aff9f1101
--- /dev/null
+++ b/libraries/BluetoothSerial/examples/SerialToSerialBT_Legacy/SerialToSerialBT_Legacy.ino
@@ -0,0 +1,66 @@
+// This example code is in the Public Domain (or CC0 licensed, at your option.)
+//
+// This example creates a bridge between Serial and Classical Bluetooth (SPP with authentication)
+// and also demonstrate that SerialBT have the same functionalities of a normal Serial
+// Legacy pairing TODO
+// Must be run as idf component ... todo
+
+#include "BluetoothSerial.h"
+
+// Check if BlueTooth is available
+#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
+  #error Bluetooth is not enabled! Please run `make menuconfig` to and enable it
+#endif
+
+// Check Serial Port Profile
+#if !defined(CONFIG_BT_SPP_ENABLED)
+  #error Serial Port Profile for BlueTooth is not available or not enabled. It is only available for the ESP32 chip.
+#endif
+
+// Check Simple Secure Pairing
+#if defined(CONFIG_BT_SSP_ENABLED)
+  #warning Legacy Pairing is disabled (the CONFIG_BT_SSP_ENABLED is enabled) disable it in menuconfig.
+  void setup(){}
+  void loop(){}
+#else
+const char * deviceName = "ESP32_Legacy_example";
+
+BluetoothSerial SerialBT;
+bool confirmRequestDone = false;
+
+void BTAuthCompleteCallback(boolean success){
+  if (success){
+    confirmRequestDone = true;
+    Serial.println("Pairing success!!");
+  }
+  else{
+    Serial.println("Pairing failed, rejected by user!!");
+  }
+}
+
+void serial_response(){
+  if (Serial.available()){
+      SerialBT.write(Serial.read());
+    }
+    if (SerialBT.available()){
+      Serial.write(SerialBT.read());
+    }
+    delay(20);
+}
+
+void setup(){
+  Serial.begin(115200);
+  SerialBT.onAuthComplete(BTAuthCompleteCallback);
+  SerialBT.begin(deviceName); // Initiate Bluetooth device with name in parameter
+  SerialBT.setPin("1234", 4);
+  Serial.printf("The device started with name \"%s\", now you can pair it with Bluetooth!\n", deviceName);
+}
+
+void loop(){
+  if (confirmRequestDone){
+    serial_response();
+  }else{
+    delay(1); // Feed the watchdog
+  }
+}
+#endif
\ No newline at end of file
diff --git a/libraries/BluetoothSerial/examples/SerialToSerialBT_SSP/SerialToSerialBT_SSP.ino b/libraries/BluetoothSerial/examples/SerialToSerialBT_SSP/SerialToSerialBT_SSP.ino
index a9d861333a1..3895ec2cbbc 100644
--- a/libraries/BluetoothSerial/examples/SerialToSerialBT_SSP/SerialToSerialBT_SSP.ino
+++ b/libraries/BluetoothSerial/examples/SerialToSerialBT_SSP/SerialToSerialBT_SSP.ino
@@ -87,7 +87,6 @@ void BTKeyRequestCallback(){
 }
 
 void BTAuthCompleteCallback(boolean success){
-  Serial.printf("BTAuthCompleteCallback(boolean success=%d)", success);
   if (success){
     confirmRequestDone = true;
     Serial.println("Pairing success!!");
diff --git a/libraries/BluetoothSerial/src/BTScan.h b/libraries/BluetoothSerial/src/BTScan.h
index 2851fdd3626..2fa1b65c50a 100644
--- a/libraries/BluetoothSerial/src/BTScan.h
+++ b/libraries/BluetoothSerial/src/BTScan.h
@@ -20,21 +20,21 @@ class BTAdvertisedDeviceSet;
 
 class BTScanResults {
 public:
-	virtual ~BTScanResults() = default;
+    virtual ~BTScanResults() = default;
 
-    virtual void        		dump(Print *print = nullptr);
-    virtual int         		getCount();
+    virtual void                dump(Print *print = nullptr);
+    virtual int                 getCount();
     virtual BTAdvertisedDevice* getDevice(int i);
 };
 
 class BTScanResultsSet : public BTScanResults {
 public:
-    void                	dump(Print *print = nullptr);
-    int                 	getCount();
-    BTAdvertisedDevice*		getDevice(int i);
+    void                       dump(Print *print = nullptr);
+    int                        getCount();
+    BTAdvertisedDevice*        getDevice(int i);
 
-	bool add(BTAdvertisedDeviceSet advertisedDevice, bool unique = true);
-	void clear();
+    bool add(BTAdvertisedDeviceSet advertisedDevice, bool unique = true);
+    void clear();
 
     std::map<std::string, BTAdvertisedDeviceSet> m_vectorAdvertisedDevices;
 };
diff --git a/libraries/BluetoothSerial/src/BluetoothSerial.cpp b/libraries/BluetoothSerial/src/BluetoothSerial.cpp
index 46a6d829754..fb0c8aea95f 100644
--- a/libraries/BluetoothSerial/src/BluetoothSerial.cpp
+++ b/libraries/BluetoothSerial/src/BluetoothSerial.cpp
@@ -28,6 +28,7 @@
 #endif
 
 #include "BluetoothSerial.h"
+#include "BTAdvertisedDevice.h"
 
 #include "esp_bt.h"
 #include "esp_bt_main.h"
@@ -71,9 +72,13 @@ static esp_bd_addr_t _peer_bd_addr;
 static char _remote_name[ESP_BT_GAP_MAX_BDNAME_LEN + 1];
 static bool _isRemoteAddressSet;
 static bool _isMaster;
-static bool _enableSSP;
-static bool _IO_CAP_INPUT;
-static bool _IO_CAP_OUTPUT;
+#ifdef CONFIG_BT_SSP_ENABLED
+  static bool _enableSSP;
+  static bool _IO_CAP_INPUT;
+  static bool _IO_CAP_OUTPUT;
+#endif
+esp_bt_pin_code_t _pin_code = {0};
+uint8_t _pin_code_len = 0; // Number of valid Bytes in the esp_bt_pin_code_t array
 static esp_spp_sec_t _sec_mask;
 static esp_spp_role_t _role;
 // start connect on ESP_SPP_DISCOVERY_COMP_EVT or save entry for getChannels
@@ -528,28 +533,23 @@ static void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *pa
                     auth_complete_callback(true);
                 }
             } else {
-                log_e("authentication failed for connecting with \"%s\", status:%d", param->auth_cmpl.device_name, param->auth_cmpl.stat);
+                log_e("authentication failed, status:%d", param->auth_cmpl.stat);
                 if (auth_complete_callback) {
                     auth_complete_callback(false);
                 }
             }
             break;
         case ESP_BT_GAP_PIN_REQ_EVT: // Enum 5 - Legacy Pairing Pin code request
-            // default pairing pins
-            log_i("ESP_BT_GAP_PIN_REQ_EVT min_16_digit:%d", param->pin_req.min_16_digit);
-            if (param->pin_req.min_16_digit) {
-                log_i("Input pin code: 0000 0000 0000 0000");
-                esp_bt_pin_code_t pin_code;
-                memset(pin_code, '0', ESP_BT_PIN_CODE_LEN);
-                esp_bt_gap_pin_reply(param->pin_req.bda, true, 16, pin_code);
+            log_i("ESP_BT_GAP_PIN_REQ_EVT (min_16_digit=%d)", param->pin_req.min_16_digit);
+            if (param->pin_req.min_16_digit && _pin_code_len < 16) {
+                esp_bt_gap_pin_reply(param->pin_req.bda, false, 0, NULL);
             } else {
-                log_i("Input pin code: 1234");
-                esp_bt_pin_code_t pin_code;
-                memcpy(pin_code, "1234", 4);
-                esp_bt_gap_pin_reply(param->pin_req.bda, true, 4, pin_code);
+                //log_i("Input pin code: \"%s\"=0x%x", _pin_code);
+                log_i("Input pin code: \"%.*s\"=0x%x", _pin_code_len, _pin_code, *(int*)_pin_code);
+                esp_bt_gap_pin_reply(param->pin_req.bda, true, _pin_code_len, _pin_code);
             }
             break;
-       
+#ifdef CONFIG_BT_SSP_ENABLED
         case ESP_BT_GAP_CFM_REQ_EVT: // Enum 6 - Security Simple Pairing User Confirmation request.
             log_i("ESP_BT_GAP_CFM_REQ_EVT Please compare the numeric value: %d", param->cfm_req.num_val);
             if (confirm_request_callback) {
@@ -561,11 +561,13 @@ static void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *pa
                 esp_bt_gap_ssp_confirm_reply(param->cfm_req.bda, false);
             }
             break;
+#endif
 
         case ESP_BT_GAP_KEY_NOTIF_EVT: // Enum 7 - Security Simple Pairing Passkey Notification
             log_i("ESP_BT_GAP_KEY_NOTIF_EVT passkey:%d", param->key_notif.passkey);
             break;
 
+#ifdef CONFIG_BT_SSP_ENABLED
         case ESP_BT_GAP_KEY_REQ_EVT: // Enum 8 - Security Simple Pairing Passkey request
             log_i("ESP_BT_GAP_KEY_REQ_EVT Please enter passkey!");
             if (key_request_callback) {
@@ -577,6 +579,7 @@ static void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *pa
                 esp_bt_gap_ssp_confirm_reply(param->cfm_req.bda, false);
             }
             break;
+#endif
 
         case ESP_BT_GAP_READ_RSSI_DELTA_EVT: // Enum 9 - Read rssi event
             log_i("ESP_BT_GAP_READ_RSSI_DELTA_EVT Read rssi event");
@@ -718,6 +721,7 @@ static bool _init_bt(const char *deviceName)
     log_i("device name set");
     esp_bt_dev_set_device_name(deviceName);
 
+#ifdef CONFIG_BT_SSP_ENABLED
     if (_enableSSP) {
         log_i("Simple Secure Pairing");
         esp_bt_sp_param_t param_type = ESP_BT_SP_IOCAP_MODE;
@@ -733,6 +737,7 @@ static bool _init_bt(const char *deviceName)
         }
         esp_bt_gap_set_security_param(param_type, &iocap, sizeof(uint8_t));
     }
+#endif
 
     // the default BTA_DM_COD_LOUDSPEAKER does not work with the macOS BT stack
     esp_bt_cod_t cod;
@@ -908,6 +913,7 @@ void BluetoothSerial::end()
     _stop_bt();
 }
 
+#ifdef CONFIG_BT_SSP_ENABLED
 void BluetoothSerial::onConfirmRequest(ConfirmRequestCb cb)
 {
     confirm_request_callback = cb;
@@ -921,6 +927,7 @@ void BluetoothSerial::onKeyRequest(KeyRequestCb cb)
 void BluetoothSerial::respondPasskey(uint32_t passkey){
     esp_bt_gap_ssp_passkey_reply(current_bd_addr, true, passkey);
 }
+#endif
 
 void BluetoothSerial::onAuthComplete(AuthCompleteCb cb)
 {
@@ -939,6 +946,7 @@ esp_err_t BluetoothSerial::register_callback(esp_spp_cb_t * callback)
     return ESP_OK;
 }
 
+#ifdef CONFIG_BT_SSP_ENABLED
 // Enable Simple Secure Pairing (using generated PIN)
 // This must be called before calling begin, otherwise has no effect!
 void BluetoothSerial::enableSSP() {
@@ -974,6 +982,19 @@ void BluetoothSerial::disableSSP() {
     _enableSSP = false;
 }
 
+#else
+
+bool BluetoothSerial::setPin(const char *pin, uint8_t pin_code_len){
+    if(pin_code_len == 0 || pin_code_len > 16){
+        log_e("PIN code must be 1-16 Bytes long! Called with length %d", pin_code_len);
+        return false;
+    }
+    _pin_code_len = pin_code_len;
+    memcpy(_pin_code, pin, pin_code_len);
+    return (esp_bt_gap_set_pin(ESP_BT_PIN_TYPE_FIXED, _pin_code_len, _pin_code) == ESP_OK);
+}
+#endif
+
 bool BluetoothSerial::connect(String remoteName)
 {
     bool retval = false;
diff --git a/libraries/BluetoothSerial/src/BluetoothSerial.h b/libraries/BluetoothSerial/src/BluetoothSerial.h
index a53af307c31..a446ee557e4 100644
--- a/libraries/BluetoothSerial/src/BluetoothSerial.h
+++ b/libraries/BluetoothSerial/src/BluetoothSerial.h
@@ -26,6 +26,8 @@
 #include <functional>
 #include <map>
 #include "BTScan.h"
+#include "BTAdvertisedDevice.h"
+
 
 typedef std::function<void(const uint8_t *buffer, size_t size)> BluetoothSerialDataCb;
 typedef std::function<void(uint32_t num_val)> ConfirmRequestCb;
@@ -56,15 +58,21 @@ class BluetoothSerial: public Stream
         void onData(BluetoothSerialDataCb cb);
         esp_err_t register_callback(esp_spp_cb_t * callback);
         
+#ifdef CONFIG_BT_SSP_ENABLED
         void onConfirmRequest(ConfirmRequestCb cb);
         void onKeyRequest(KeyRequestCb cb);
         void respondPasskey(uint32_t passkey);
+#endif
         void onAuthComplete(AuthCompleteCb cb);
         void confirmReply(boolean confirm);
 
+#ifdef CONFIG_BT_SSP_ENABLED
         void enableSSP();
         void enableSSP(bool inputCapability, bool outputCapability);
         void disableSSP();
+#else
+        bool setPin(const char *pin, uint8_t pin_code_len);
+#endif
         bool connect(String remoteName);
         bool connect(uint8_t remoteAddress[], int channel=0, esp_spp_sec_t sec_mask=(ESP_SPP_SEC_ENCRYPT|ESP_SPP_SEC_AUTHENTICATE), esp_spp_role_t role=ESP_SPP_ROLE_MASTER);
         bool connect(const BTAddress &remoteAddress, int channel=0, esp_spp_sec_t sec_mask=(ESP_SPP_SEC_ENCRYPT|ESP_SPP_SEC_AUTHENTICATE), esp_spp_role_t role=ESP_SPP_ROLE_MASTER) {

From be66f01f35ae3324e1550651da12d0ff7873aad6 Mon Sep 17 00:00:00 2001
From: Tomas Pilny <tomas.pilny@espressif.com>
Date: Thu, 10 Aug 2023 11:02:13 +0200
Subject: [PATCH 12/14] Spelling fixes in README

---
 libraries/BluetoothSerial/README.md | 21 +++++++++++----------
 1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/libraries/BluetoothSerial/README.md b/libraries/BluetoothSerial/README.md
index 14348519b51..15b3835b2f5 100644
--- a/libraries/BluetoothSerial/README.md
+++ b/libraries/BluetoothSerial/README.md
@@ -25,12 +25,12 @@ There are 3 basic use cases: phone, other ESP32 or any MCU with BT serial module
 
 #### ESP32
 
-You can flash one of the ESP32 with example [`SerialToSerialBTM`](https://github.com/espressif/arduino-esp32/blob/master/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino) (the Master) and another ESP32 with [`SerialToSerialBT`](https://github.com/espressif/arduino-esp32/blob/master/libraries/BluetoothSerial/examples/SerialToSerialBT/SerialToSerialBT.ino) (the Slave).
-Those examples are pre-set to work out-of-the box but they should be scalable to connect multiple Slaves to the Master.
+You can flash one of the ESP32 with the example [`SerialToSerialBTM`](https://github.com/espressif/arduino-esp32/blob/master/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino) (the Master) and another ESP32 with [`SerialToSerialBT`](https://github.com/espressif/arduino-esp32/blob/master/libraries/BluetoothSerial/examples/SerialToSerialBT/SerialToSerialBT.ino) (the Slave).
+Those examples are preset to work out-of-the-box but they should be scalable to connect multiple Slaves to the Master.
 
 #### 3rd party Serial BT module
 
-Using 3rd party Serial BT module will require to study the documentation of the particular module in order to make it work, however one side can utilize the mentioned [`SerialToSerialBTM`](https://github.com/espressif/arduino-esp32/blob/master/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino) (the Master) or [`SerialToSerialBT`](https://github.com/espressif/arduino-esp32/blob/master/libraries/BluetoothSerial/examples/SerialToSerialBT/SerialToSerialBT.ino) (the Slave).
+Using 3rd party Serial BT module will require to study the documentation of the particular module in order to make it work, however, one side can utilize the mentioned [`SerialToSerialBTM`](https://github.com/espressif/arduino-esp32/blob/master/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino) (the Master) or [`SerialToSerialBT`](https://github.com/espressif/arduino-esp32/blob/master/libraries/BluetoothSerial/examples/SerialToSerialBT/SerialToSerialBT.ino) (the Slave).
 
 ### Pairing options
 
@@ -46,12 +46,12 @@ This method will authenticate automatically any attempt to pair and should not b
 
 ### With SSP
 
-Usage of SSP provides secure connection. This option is demonstrated in example [`SerialToSerialBT_SSP`](https://github.com/espressif/arduino-esp32/blob/master/libraries/BluetoothSerial/examples/SerialToSerialBT_SSP/SerialToSerialBT_SSP.ino)
+The usage of SSP provides a secure connection. This option is demonstrated in the example `SerialToSerialBT_SSP``](https://github.com/espressif/arduino-esp32/blob/master/libraries/BluetoothSerial/examples/SerialToSerialBT_SSP/SerialToSerialBT_SSP.ino)
 
-The Secure Simple Pairing is enable by calling method `enableSSP` which has two variants - one is backward compatible without parameter `enableSSP()` and second with parameters `enableSSP(bool inputCapability, bool outputCapability)`.
-Alternatively the SSP can be disabled by `disableSSP()`
+The Secure Simple Pairing is enabled by calling method `enableSSP` which has two variants - one is backward compatible without parameter `enableSSP()` and second with parameters `enableSSP(bool inputCapability, bool outputCapability)`.
+Alternatively, the SSP can be disabled by `disableSSP()`
 
-Both options must be called before `begin()` or if it is called after `begin()` the driver needs to be restart (call `end()` followed by `begin()`) in order to take in effect enabling or disabling the SSP.
+Both options must be called before `begin()` or if it is called after `begin()` the driver needs to be restarted (call `end()` followed by `begin()`) in order to take in effect enabling or disabling the SSP.
 
 #### The parameters define the method of authentication:
 
@@ -61,7 +61,7 @@ Both options must be called before `begin()` or if it is called after `begin()`
 
 * **inputCapability=true and outputCapability=true**
     * Both devices display randomly generated code and if they match the user will authenticate pairing on both devices.
-    * This must be implemented registering callback via `onConfirmRequest()` and in this callback the user will input the response and call `confirmReply(true)` if the authenticated, otherwise call `confirmReply(false)` to reject the pairing.
+    * This must be implemented by registering a callback via `onConfirmRequest()` and in this callback the user will input the response and call `confirmReply(true)` if the authenticated, otherwise call `confirmReply(false)` to reject the pairing.
 * **inputCapability=false and outputCapability=false**
     * Only the other device authenticates pairing without any pin.
 * **inputCapability=false and outputCapability=true**
@@ -74,5 +74,6 @@ Both options must be called before `begin()` or if it is called after `begin()`
 
 To use Legacy pairing you will have to use [Arduino as an IDF component](https://espressif-docs.readthedocs-hosted.com/projects/arduino-esp32/en/latest/esp-idf_component.html) and disable option `CONFIG_BT_SSP_ENABLED`.
 Please refer to the documentation on how to setup Arduino as an IDF component and when you are done, run `idf.py menuconfig` navigate to `Component Config -> Bluetooth -> Bluedroid -> [ ] Secure Simple Pairing` and disable it.
-While in the menuconfig you will also need to change partition scheme `Partition Table -> Partition Table -> (X) Single Factory app (large), no OTA`.
-After these changes save & quit menuconfig a you are ready to go: `idf.py  monitor flash`.
\ No newline at end of file
+While in the menuconfig you will also need to change the partition scheme `Partition Table -> Partition Table -> (X) Single Factory app (large), no OTA`.
+After these changes save & quit menuconfig and you are ready to go: `idf.py  monitor flash`.
+Please note that to use the PIN in smartphones and computers you need to use characters `SerialBT.setPin("1234", 4);` not a number `SerialBT.setPin(1234, 4);` . Numbers CAN be used if the other side uses them too, but phones and computers use characters.
\ No newline at end of file

From f419cd5667f83e75ef584e1d9885b4206ab6f257 Mon Sep 17 00:00:00 2001
From: Tomas Pilny <tomas.pilny@espressif.com>
Date: Tue, 15 Aug 2023 15:07:02 +0200
Subject: [PATCH 13/14] Removed unnecessary test in discover()

---
 libraries/BluetoothSerial/src/BluetoothSerial.cpp | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/libraries/BluetoothSerial/src/BluetoothSerial.cpp b/libraries/BluetoothSerial/src/BluetoothSerial.cpp
index fb0c8aea95f..f88db39d928 100644
--- a/libraries/BluetoothSerial/src/BluetoothSerial.cpp
+++ b/libraries/BluetoothSerial/src/BluetoothSerial.cpp
@@ -1006,7 +1006,7 @@ bool BluetoothSerial::connect(String remoteName)
     }
     disconnect();
     _doConnect = true;
-    _isRemoteAddressSet = false;
+    _isRemoteAddressSet = true;
     _sec_mask = ESP_SPP_SEC_ENCRYPT|ESP_SPP_SEC_AUTHENTICATE;
     _role = ESP_SPP_ROLE_MASTER;
     strncpy(_remote_name, remoteName.c_str(), ESP_BT_GAP_MAX_BDNAME_LEN);
@@ -1169,8 +1169,10 @@ bool BluetoothSerial::isReady(bool checkMaster, int timeout) {
  */
 BTScanResults* BluetoothSerial::discover(int timeoutMs) {
     scanResults.clear();
-    if (timeoutMs < MIN_INQ_TIME || timeoutMs > MAX_INQ_TIME || strlen(_remote_name) || _isRemoteAddressSet)
+    if (timeoutMs < MIN_INQ_TIME || timeoutMs > MAX_INQ_TIME){
+        log_e("Timeout out of bounds: MIN=%d; MAX=%d; requested=%d", MIN_INQ_TIME, MAX_INQ_TIME, timeoutMs);
         return nullptr;
+    }
     int timeout = timeoutMs / INQ_TIME;
     log_i("discover::disconnect");
     disconnect();

From 22b2e44a6aaf17677a173d44fcc836b3c5e703e2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Piln=C3=BD?= <pilnyt@seznam.cz>
Date: Thu, 24 Aug 2023 11:30:48 +0200
Subject: [PATCH 14/14] Updates

---
 .github/ISSUE_TEMPLATE/Issue-report.yml       |  1 +
 cores/esp32/HWCDC.cpp                         | 15 +++++--
 cores/esp32/esp32-hal-bt.c                    |  4 ++
 cores/esp32/esp32-hal-misc.c                  |  6 +++
 libraries/BluetoothSerial/README.md           |  9 ++--
 .../DiscoverConnect/DiscoverConnect.ino       |  4 +-
 .../SerialToSerialBT/SerialToSerialBT.ino     |  4 +-
 .../SerialToSerialBTM/SerialToSerialBTM.ino   |  4 +-
 .../SerialToSerialBT_Legacy.ino               | 25 +++++------
 .../SerialToSerialBT_SSP.ino                  | 45 +++++++++----------
 .../bt_remove_paired_devices.ino              |  6 +--
 .../BluetoothSerial/src/BluetoothSerial.cpp   |  7 ++-
 .../examples/WebUpdater/WebUpdater.ino        |  3 +-
 13 files changed, 74 insertions(+), 59 deletions(-)

diff --git a/.github/ISSUE_TEMPLATE/Issue-report.yml b/.github/ISSUE_TEMPLATE/Issue-report.yml
index 05d929c87b9..3628cba1fca 100644
--- a/.github/ISSUE_TEMPLATE/Issue-report.yml
+++ b/.github/ISSUE_TEMPLATE/Issue-report.yml
@@ -41,6 +41,7 @@ body:
       options:
         - latest master (checkout manually)
         - latest development Release Candidate (RC-X)
+        - v2.0.11
         - v2.0.10
         - v2.0.9
         - v2.0.8
diff --git a/cores/esp32/HWCDC.cpp b/cores/esp32/HWCDC.cpp
index 245b73109d9..189eb3b6fc5 100644
--- a/cores/esp32/HWCDC.cpp
+++ b/cores/esp32/HWCDC.cpp
@@ -200,9 +200,18 @@ void HWCDC::begin(unsigned long baud)
     if(tx_lock == NULL) {
         tx_lock = xSemaphoreCreateMutex();
     }
-    setRxBufferSize(256);//default if not preset
-    setTxBufferSize(256);//default if not preset
-
+    //RX Buffer default has 256 bytes if not preset
+    if(rx_queue == NULL) {
+        if (!setRxBufferSize(256)) {
+            log_e("HW CDC RX Buffer error");
+        }
+    }
+    //TX Buffer default has 256 bytes if not preset
+    if (tx_ring_buf == NULL) {
+        if (!setTxBufferSize(256)) {
+            log_e("HW CDC TX Buffer error");
+        }    
+    }
     usb_serial_jtag_ll_disable_intr_mask(USB_SERIAL_JTAG_LL_INTR_MASK);
     usb_serial_jtag_ll_clr_intsts_mask(USB_SERIAL_JTAG_LL_INTR_MASK);
     usb_serial_jtag_ll_ena_intr_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY | USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT | USB_SERIAL_JTAG_INTR_BUS_RESET);
diff --git a/cores/esp32/esp32-hal-bt.c b/cores/esp32/esp32-hal-bt.c
index d2084bda3f3..f6b174e4203 100644
--- a/cores/esp32/esp32-hal-bt.c
+++ b/cores/esp32/esp32-hal-bt.c
@@ -17,8 +17,12 @@
 #if SOC_BT_SUPPORTED
 #ifdef CONFIG_BT_ENABLED
 
+#if CONFIG_IDF_TARGET_ESP32
+bool btInUse(){ return true; }
+#else
 // user may want to change it to free resources
 __attribute__((weak)) bool btInUse(){ return true; }
+#endif
 
 #include "esp_bt.h"
 
diff --git a/cores/esp32/esp32-hal-misc.c b/cores/esp32/esp32-hal-misc.c
index bc368b53722..6a7931117ad 100644
--- a/cores/esp32/esp32-hal-misc.c
+++ b/cores/esp32/esp32-hal-misc.c
@@ -243,9 +243,15 @@ bool verifyRollbackLater() { return false; }
 #endif
 
 #ifdef CONFIG_BT_ENABLED
+#if CONFIG_IDF_TARGET_ESP32
+//overwritten in esp32-hal-bt.c
+bool btInUse() __attribute__((weak));
+bool btInUse(){ return false; }
+#else
 //from esp32-hal-bt.c
 extern bool btInUse();
 #endif
+#endif
 
 void initArduino()
 {
diff --git a/libraries/BluetoothSerial/README.md b/libraries/BluetoothSerial/README.md
index 15b3835b2f5..4989b3a088c 100644
--- a/libraries/BluetoothSerial/README.md
+++ b/libraries/BluetoothSerial/README.md
@@ -6,7 +6,7 @@ Note: Since version 3.0.0 this library does not support legacy pairing (using fi
 
 ### How to use it?
 
-There are 3 basic use cases: phone, other ESP32 or any MCU with BT serial module
+There are 3 basic use cases: phone, other ESP32 or any MCU with a Bluetooth serial module
 
 #### Phone
 
@@ -28,9 +28,9 @@ There are 3 basic use cases: phone, other ESP32 or any MCU with BT serial module
 You can flash one of the ESP32 with the example [`SerialToSerialBTM`](https://github.com/espressif/arduino-esp32/blob/master/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino) (the Master) and another ESP32 with [`SerialToSerialBT`](https://github.com/espressif/arduino-esp32/blob/master/libraries/BluetoothSerial/examples/SerialToSerialBT/SerialToSerialBT.ino) (the Slave).
 Those examples are preset to work out-of-the-box but they should be scalable to connect multiple Slaves to the Master.
 
-#### 3rd party Serial BT module
+#### 3rd party Serial Bluetooth module
 
-Using 3rd party Serial BT module will require to study the documentation of the particular module in order to make it work, however, one side can utilize the mentioned [`SerialToSerialBTM`](https://github.com/espressif/arduino-esp32/blob/master/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino) (the Master) or [`SerialToSerialBT`](https://github.com/espressif/arduino-esp32/blob/master/libraries/BluetoothSerial/examples/SerialToSerialBT/SerialToSerialBT.ino) (the Slave).
+Using a 3rd party Serial Bluetooth module will require to study the documentation of the particular module in order to make it work, however, one side can utilize the mentioned [`SerialToSerialBTM`](https://github.com/espressif/arduino-esp32/blob/master/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino) (the Master) or [`SerialToSerialBT`](https://github.com/espressif/arduino-esp32/blob/master/libraries/BluetoothSerial/examples/SerialToSerialBT/SerialToSerialBT.ino) (the Slave).
 
 ### Pairing options
 
@@ -48,8 +48,7 @@ This method will authenticate automatically any attempt to pair and should not b
 
 The usage of SSP provides a secure connection. This option is demonstrated in the example `SerialToSerialBT_SSP``](https://github.com/espressif/arduino-esp32/blob/master/libraries/BluetoothSerial/examples/SerialToSerialBT_SSP/SerialToSerialBT_SSP.ino)
 
-The Secure Simple Pairing is enabled by calling method `enableSSP` which has two variants - one is backward compatible without parameter `enableSSP()` and second with parameters `enableSSP(bool inputCapability, bool outputCapability)`.
-Alternatively, the SSP can be disabled by `disableSSP()`
+The Secure Simple Pairing is enabled by calling method `enableSSP` which has two variants - one is backward compatible without parameter `enableSSP()` and second with parameters `enableSSP(bool inputCapability, bool outputCapability)`. Similarly, the SSP can be disabled by calling `disableSSP()`.
 
 Both options must be called before `begin()` or if it is called after `begin()` the driver needs to be restarted (call `end()` followed by `begin()`) in order to take in effect enabling or disabling the SSP.
 
diff --git a/libraries/BluetoothSerial/examples/DiscoverConnect/DiscoverConnect.ino b/libraries/BluetoothSerial/examples/DiscoverConnect/DiscoverConnect.ino
index e5d5e676c91..4269598b80f 100644
--- a/libraries/BluetoothSerial/examples/DiscoverConnect/DiscoverConnect.ino
+++ b/libraries/BluetoothSerial/examples/DiscoverConnect/DiscoverConnect.ino
@@ -29,8 +29,8 @@
 BluetoothSerial SerialBT;
 
 #define BT_DISCOVER_TIME  10000
-esp_spp_sec_t sec_mask=ESP_SPP_SEC_NONE; // or ESP_SPP_SEC_ENCRYPT|ESP_SPP_SEC_AUTHENTICATE to request pincode confirmation
-esp_spp_role_t role=ESP_SPP_ROLE_SLAVE; // or ESP_SPP_ROLE_MASTER
+esp_spp_sec_t sec_mask = ESP_SPP_SEC_NONE; // or ESP_SPP_SEC_ENCRYPT|ESP_SPP_SEC_AUTHENTICATE to request pincode confirmation
+esp_spp_role_t role = ESP_SPP_ROLE_SLAVE; // or ESP_SPP_ROLE_MASTER
 
 // std::map<BTAddress, BTAdvertisedDeviceSet> btDeviceList;
 
diff --git a/libraries/BluetoothSerial/examples/SerialToSerialBT/SerialToSerialBT.ino b/libraries/BluetoothSerial/examples/SerialToSerialBT/SerialToSerialBT.ino
index 69efeff64c6..c5ac06b992f 100644
--- a/libraries/BluetoothSerial/examples/SerialToSerialBT/SerialToSerialBT.ino
+++ b/libraries/BluetoothSerial/examples/SerialToSerialBT/SerialToSerialBT.ino
@@ -9,14 +9,14 @@
 
 String device_name = "ESP32-BT-Slave";
 
-// Check if BlueTooth is available
+// Check if Bluetooth is available
 #if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
   #error Bluetooth is not enabled! Please run `make menuconfig` to and enable it
 #endif
 
 // Check Serial Port Profile
 #if !defined(CONFIG_BT_SPP_ENABLED)
-  #error Serial Port Profile for BlueTooth is not available or not enabled. It is only available for the ESP32 chip.
+  #error Serial Port Profile for Bluetooth is not available or not enabled. It is only available for the ESP32 chip.
 #endif
 
 BluetoothSerial SerialBT;
diff --git a/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino b/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino
index 637ab2cd1da..a4917bfa141 100644
--- a/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino
+++ b/libraries/BluetoothSerial/examples/SerialToSerialBTM/SerialToSerialBTM.ino
@@ -19,14 +19,14 @@
 
 #define USE_NAME // Comment this to use MAC address instead of a slaveName
 
-// Check if BlueTooth is available
+// Check if Bluetooth is available
 #if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
   #error Bluetooth is not enabled! Please run `make menuconfig` to and enable it
 #endif
 
 // Check Serial Port Profile
 #if !defined(CONFIG_BT_SPP_ENABLED)
-  #error Serial Port Profile for BlueTooth is not available or not enabled. It is only available for the ESP32 chip.
+  #error Serial Port Profile for Bluetooth is not available or not enabled. It is only available for the ESP32 chip.
 #endif
 BluetoothSerial SerialBT;
 
diff --git a/libraries/BluetoothSerial/examples/SerialToSerialBT_Legacy/SerialToSerialBT_Legacy.ino b/libraries/BluetoothSerial/examples/SerialToSerialBT_Legacy/SerialToSerialBT_Legacy.ino
index 27aff9f1101..2343b5ca93d 100644
--- a/libraries/BluetoothSerial/examples/SerialToSerialBT_Legacy/SerialToSerialBT_Legacy.ino
+++ b/libraries/BluetoothSerial/examples/SerialToSerialBT_Legacy/SerialToSerialBT_Legacy.ino
@@ -7,19 +7,19 @@
 
 #include "BluetoothSerial.h"
 
-// Check if BlueTooth is available
+// Check if Bluetooth is available
 #if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
   #error Bluetooth is not enabled! Please run `make menuconfig` to and enable it
 #endif
 
 // Check Serial Port Profile
 #if !defined(CONFIG_BT_SPP_ENABLED)
-  #error Serial Port Profile for BlueTooth is not available or not enabled. It is only available for the ESP32 chip.
+  #error Serial Port Profile for Bluetooth is not available or not enabled. It is only available for the ESP32 chip.
 #endif
 
 // Check Simple Secure Pairing
 #if defined(CONFIG_BT_SSP_ENABLED)
-  #warning Legacy Pairing is disabled (the CONFIG_BT_SSP_ENABLED is enabled) disable it in menuconfig.
+  #warning Legacy Pairing is disabled (CONFIG_BT_SSP_ENABLED is enabled. Disable it in menuconfig).
   void setup(){}
   void loop(){}
 #else
@@ -32,20 +32,19 @@ void BTAuthCompleteCallback(boolean success){
   if (success){
     confirmRequestDone = true;
     Serial.println("Pairing success!!");
-  }
-  else{
+  } else {
     Serial.println("Pairing failed, rejected by user!!");
   }
 }
 
 void serial_response(){
   if (Serial.available()){
-      SerialBT.write(Serial.read());
-    }
-    if (SerialBT.available()){
-      Serial.write(SerialBT.read());
-    }
-    delay(20);
+    SerialBT.write(Serial.read());
+  }
+  if (SerialBT.available()){
+    Serial.write(SerialBT.read());
+  }
+  delay(20);
 }
 
 void setup(){
@@ -59,8 +58,8 @@ void setup(){
 void loop(){
   if (confirmRequestDone){
     serial_response();
-  }else{
+  } else {
     delay(1); // Feed the watchdog
   }
 }
-#endif
\ No newline at end of file
+#endif
diff --git a/libraries/BluetoothSerial/examples/SerialToSerialBT_SSP/SerialToSerialBT_SSP.ino b/libraries/BluetoothSerial/examples/SerialToSerialBT_SSP/SerialToSerialBT_SSP.ino
index 3895ec2cbbc..a39dbf1a064 100644
--- a/libraries/BluetoothSerial/examples/SerialToSerialBT_SSP/SerialToSerialBT_SSP.ino
+++ b/libraries/BluetoothSerial/examples/SerialToSerialBT_SSP/SerialToSerialBT_SSP.ino
@@ -12,19 +12,19 @@
 
 //#define AUTO_PAIR // Uncomment to automatically authenticate ESP32 side
 
-// Check if BlueTooth is available
+// Check if Bluetooth is available
 #if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
   #error Bluetooth is not enabled! Please run `make menuconfig` to and enable it
 #endif
 
 // Check Serial Port Profile
 #if !defined(CONFIG_BT_SPP_ENABLED)
-  #error Serial Port Profile for BlueTooth is not available or not enabled. It is only available for the ESP32 chip.
+  #error Serial Port Profile for Bluetooth is not available or not enabled. It is only available for the ESP32 chip.
 #endif
 
 // Check Simple Secure Pairing
 #if !defined(CONFIG_BT_SSP_ENABLED)
-  #error Simple Secure Pairing for BlueTooth is not available or not enabled.
+  #error Simple Secure Pairing for Bluetooth is not available or not enabled.
 #endif
 
 const char * deviceName = "ESP32_SSP_example";
@@ -48,17 +48,17 @@ void BTConfirmRequestCallback(uint32_t numVal){
 #ifndef AUTO_PAIR
   Serial.printf("The PIN is: %06lu. If it matches number displayed on the other device write \'Y\' or \'y\':\n", numVal); // Note the formatting "%06lu" - PIN can start with zero(s) which would be ignored with simple "%lu"
   while (!Serial.available()) {
-      delay(1); // Feed the watchdog
-      // Wait until data is available on the Serial port.
-    }
-    Serial.printf("Oh you sent %d Bytes, lets see...", Serial.available());
-    int dat = Serial.read();
-    if (dat == 'Y' || dat == 'y'){
-      SerialBT.confirmReply(true);
-    }
-    else{
-      SerialBT.confirmReply(false);
-    }
+    delay(1); // Feed the watchdog
+    // Wait until data is available on the Serial port.
+  }
+  Serial.printf("Oh you sent %d Bytes, lets see...", Serial.available());
+  int dat = Serial.read();
+  if (dat == 'Y' || dat == 'y'){
+    SerialBT.confirmReply(true);
+  }
+  else{
+    SerialBT.confirmReply(false);
+  }
 #else
   SerialBT.confirmReply(true);
 #endif
@@ -90,20 +90,19 @@ void BTAuthCompleteCallback(boolean success){
   if (success){
     confirmRequestDone = true;
     Serial.println("Pairing success!!");
-  }
-  else{
+  } else {
     Serial.println("Pairing failed, rejected by user!!");
   }
 }
 
 void serial_response(){
   if (Serial.available()){
-      SerialBT.write(Serial.read());
-    }
-    if (SerialBT.available()){
-      Serial.write(SerialBT.read());
-    }
-    delay(20);
+    SerialBT.write(Serial.read());
+  }
+  if (SerialBT.available()){
+    Serial.write(SerialBT.read());
+  }
+  delay(20);
 }
 
 void setup(){
@@ -129,7 +128,7 @@ void setup(){
 void loop(){
   if (confirmRequestDone){
     serial_response();
-  }else{
+  } else {
     delay(1); // Feed the watchdog
   }
 }
diff --git a/libraries/BluetoothSerial/examples/bt_remove_paired_devices/bt_remove_paired_devices.ino b/libraries/BluetoothSerial/examples/bt_remove_paired_devices/bt_remove_paired_devices.ino
index b2449d80ea5..d6f6786828a 100755
--- a/libraries/BluetoothSerial/examples/bt_remove_paired_devices/bt_remove_paired_devices.ino
+++ b/libraries/BluetoothSerial/examples/bt_remove_paired_devices/bt_remove_paired_devices.ino
@@ -43,7 +43,7 @@ void setup(){
   int count = SerialBT.getNumberOfBondedDevices();
   if(!count){
     Serial.println("No bonded devices found.");
-  }else{
+  } else {
     Serial.printf("Bonded device count: %d\n", count);
     if(PAIR_MAX_DEVICES < count){
       count = PAIR_MAX_DEVICES;
@@ -62,7 +62,7 @@ void setup(){
         if(REMOVE_BONDED_DEVICES){
           if(SerialBT.deleteBondedDevice(pairedDeviceBtAddr[i])){
             Serial.printf("Removed bonded device # %d\n", i);
-          }else{
+          } else {
             Serial.printf("Failed to remove bonded device # %d", i);
           } // if(ESP_OK == tError)
         } // if(REMOVE_BONDED_DEVICES)
@@ -71,4 +71,4 @@ void setup(){
   } // if(!count)
 }
 
-void loop() {}
\ No newline at end of file
+void loop() {}
diff --git a/libraries/BluetoothSerial/src/BluetoothSerial.cpp b/libraries/BluetoothSerial/src/BluetoothSerial.cpp
index f88db39d928..419809d3f25 100644
--- a/libraries/BluetoothSerial/src/BluetoothSerial.cpp
+++ b/libraries/BluetoothSerial/src/BluetoothSerial.cpp
@@ -573,8 +573,7 @@ static void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *pa
             if (key_request_callback) {
                 memcpy(current_bd_addr, param->cfm_req.bda, sizeof(esp_bd_addr_t));
                 key_request_callback();
-            }
-            else {
+            } else {
                 log_w("ESP_BT_GAP_KEY_REQ_EVT: key_request_callback does not exist - refuseing pairing");
                 esp_bt_gap_ssp_confirm_reply(param->cfm_req.bda, false);
             }
@@ -1355,7 +1354,7 @@ void BluetoothSerial::deleteAllBondedDevices(){
     if(expected_dev_num == 0){
         log_i("No devices in cache.");
         return;
-    }else{
+    } else {
         log_d("Found %d bonded devices", expected_dev_num);
     }
     esp_err_t ret;
@@ -1382,7 +1381,7 @@ void BluetoothSerial::deleteAllBondedDevices(){
             log_d("esp_bt_gap_remove_bond_device ret = %d", ret);
             if(ret == ESP_OK){
                 log_d("Removed bonded device #%d", i);
-            }else{
+            } else {
                 log_w("Failed to removed bonded device #%d", i);
             }
             //btc_storage_remove_bonded_device(dev_list[i]);
diff --git a/libraries/HTTPUpdateServer/examples/WebUpdater/WebUpdater.ino b/libraries/HTTPUpdateServer/examples/WebUpdater/WebUpdater.ino
index f2503a7efe1..21688c3e7c2 100644
--- a/libraries/HTTPUpdateServer/examples/WebUpdater/WebUpdater.ino
+++ b/libraries/HTTPUpdateServer/examples/WebUpdater/WebUpdater.ino
@@ -33,8 +33,7 @@ void setup(void) {
     Serial.println("WiFi failed, retrying.");
   }
 
-  MDNS.begin(host);
-  if (MDNS.begin("esp32")) {
+  if (MDNS.begin(host)) {
     Serial.println("mDNS responder started");
   }