From bf8cfac94f22f8fbfde9ef59741de61588358e74 Mon Sep 17 00:00:00 2001 From: Tomas Pilny 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 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 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 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 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 BluetoothSerialDataCb; typedef std::function ConfirmRequestCb; +typedef std::function KeyRequestCb; typedef std::function AuthCompleteCb; typedef std::function 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 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 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
-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 +#### 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 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 #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 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 #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 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 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 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 #include #include "BTScan.h" +#include "BTAdvertisedDevice.h" + typedef std::function BluetoothSerialDataCb; typedef std::function 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 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 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?= 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 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"); }