Skip to content

Commit 672395f

Browse files
committed
Re-implemented legacy pairing support
1 parent 8a7cdb8 commit 672395f

File tree

11 files changed

+133
-28
lines changed

11 files changed

+133
-28
lines changed

libraries/BluetoothSerial/README.md

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,11 @@ Using 3rd party Serial BT module will require to study the documentation of the
3434

3535
### Pairing options
3636

37-
There are two major options - with and without Secure Simple Pairing (SSP).
37+
There are two easy options and one difficult.
38+
39+
The easy options can be used as usual. These offer pairing with and without Secure Simple Pairing (SSP).
40+
41+
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`.
3842

3943
#### Without SSP
4044

@@ -63,5 +67,12 @@ Both options must be called before `begin()` or if it is called after `begin()`
6367
* **inputCapability=false and outputCapability=true**
6468
* Only the other device authenticates pairing without any pin.
6569
* **inputCapability=true and outputCapability=false**
66-
* User will be required to input the passkey to the ESP32 device to authenticate.
67-
* This must be implemented by registering callback via `onKeyRequest()` and in this callback the entered passkey will be responded via `respondPasskey(passkey)`
70+
* The user will be required to input the passkey to the ESP32 device to authenticate.
71+
* This must be implemented by registering a callback via `onKeyRequest`()` and in this callback the entered passkey will be responded via `respondPasskey(passkey)`
72+
73+
### Legacy Pairing (IDF component)
74+
75+
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`.
76+
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.
77+
While in the menuconfig you will also need to change partition scheme `Partition Table -> Partition Table -> (X) Single Factory app (large), no OTA`.
78+
After these changes save & quit menuconfig a you are ready to go: `idf.py monitor flash`.

libraries/BluetoothSerial/examples/SerialToSerialBT_Legacy/.skip.esp32c3

Whitespace-only changes.

libraries/BluetoothSerial/examples/SerialToSerialBT_Legacy/.skip.esp32c6

Whitespace-only changes.

libraries/BluetoothSerial/examples/SerialToSerialBT_Legacy/.skip.esp32h2

Whitespace-only changes.

libraries/BluetoothSerial/examples/SerialToSerialBT_Legacy/.skip.esp32s2

Whitespace-only changes.

libraries/BluetoothSerial/examples/SerialToSerialBT_Legacy/.skip.esp32s3

Whitespace-only changes.
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
// This example code is in the Public Domain (or CC0 licensed, at your option.)
2+
//
3+
// This example creates a bridge between Serial and Classical Bluetooth (SPP with authentication)
4+
// and also demonstrate that SerialBT have the same functionalities of a normal Serial
5+
// Legacy pairing TODO
6+
// Must be run as idf component ... todo
7+
8+
#include "BluetoothSerial.h"
9+
10+
// Check if BlueTooth is available
11+
#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
12+
#error Bluetooth is not enabled! Please run `make menuconfig` to and enable it
13+
#endif
14+
15+
// Check Serial Port Profile
16+
#if !defined(CONFIG_BT_SPP_ENABLED)
17+
#error Serial Port Profile for BlueTooth is not available or not enabled. It is only available for the ESP32 chip.
18+
#endif
19+
20+
// Check Simple Secure Pairing
21+
#if defined(CONFIG_BT_SSP_ENABLED)
22+
#warning Legacy Pairing is disabled (the CONFIG_BT_SSP_ENABLED is enabled) disable it in menuconfig.
23+
void setup(){}
24+
void loop(){}
25+
#else
26+
const char * deviceName = "ESP32_Legacy_example";
27+
28+
BluetoothSerial SerialBT;
29+
bool confirmRequestDone = false;
30+
31+
void BTAuthCompleteCallback(boolean success){
32+
if (success){
33+
confirmRequestDone = true;
34+
Serial.println("Pairing success!!");
35+
}
36+
else{
37+
Serial.println("Pairing failed, rejected by user!!");
38+
}
39+
}
40+
41+
void serial_response(){
42+
if (Serial.available()){
43+
SerialBT.write(Serial.read());
44+
}
45+
if (SerialBT.available()){
46+
Serial.write(SerialBT.read());
47+
}
48+
delay(20);
49+
}
50+
51+
void setup(){
52+
Serial.begin(115200);
53+
SerialBT.onAuthComplete(BTAuthCompleteCallback);
54+
SerialBT.begin(deviceName); // Initiate Bluetooth device with name in parameter
55+
SerialBT.setPin("1234", 4);
56+
Serial.printf("The device started with name \"%s\", now you can pair it with Bluetooth!\n", deviceName);
57+
}
58+
59+
void loop(){
60+
if (confirmRequestDone){
61+
serial_response();
62+
}else{
63+
delay(1); // Feed the watchdog
64+
}
65+
}
66+
#endif

libraries/BluetoothSerial/examples/SerialToSerialBT_SSP/SerialToSerialBT_SSP.ino

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,6 @@ void BTKeyRequestCallback(){
8787
}
8888

8989
void BTAuthCompleteCallback(boolean success){
90-
Serial.printf("BTAuthCompleteCallback(boolean success=%d)", success);
9190
if (success){
9291
confirmRequestDone = true;
9392
Serial.println("Pairing success!!");

libraries/BluetoothSerial/src/BTScan.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,21 +20,21 @@ class BTAdvertisedDeviceSet;
2020

2121
class BTScanResults {
2222
public:
23-
virtual ~BTScanResults() = default;
23+
virtual ~BTScanResults() = default;
2424

25-
virtual void dump(Print *print = nullptr);
26-
virtual int getCount();
25+
virtual void dump(Print *print = nullptr);
26+
virtual int getCount();
2727
virtual BTAdvertisedDevice* getDevice(int i);
2828
};
2929

3030
class BTScanResultsSet : public BTScanResults {
3131
public:
32-
void dump(Print *print = nullptr);
33-
int getCount();
34-
BTAdvertisedDevice* getDevice(int i);
32+
void dump(Print *print = nullptr);
33+
int getCount();
34+
BTAdvertisedDevice* getDevice(int i);
3535

36-
bool add(BTAdvertisedDeviceSet advertisedDevice, bool unique = true);
37-
void clear();
36+
bool add(BTAdvertisedDeviceSet advertisedDevice, bool unique = true);
37+
void clear();
3838

3939
std::map<std::string, BTAdvertisedDeviceSet> m_vectorAdvertisedDevices;
4040
};

libraries/BluetoothSerial/src/BluetoothSerial.cpp

Lines changed: 37 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#endif
2929

3030
#include "BluetoothSerial.h"
31+
#include "BTAdvertisedDevice.h"
3132

3233
#include "esp_bt.h"
3334
#include "esp_bt_main.h"
@@ -71,9 +72,13 @@ static esp_bd_addr_t _peer_bd_addr;
7172
static char _remote_name[ESP_BT_GAP_MAX_BDNAME_LEN + 1];
7273
static bool _isRemoteAddressSet;
7374
static bool _isMaster;
74-
static bool _enableSSP;
75-
static bool _IO_CAP_INPUT;
76-
static bool _IO_CAP_OUTPUT;
75+
#ifdef CONFIG_BT_SSP_ENABLED
76+
static bool _enableSSP;
77+
static bool _IO_CAP_INPUT;
78+
static bool _IO_CAP_OUTPUT;
79+
#endif
80+
esp_bt_pin_code_t _pin_code = {0};
81+
uint8_t _pin_code_len = 0; // Number of valid Bytes in the esp_bt_pin_code_t array
7782
static esp_spp_sec_t _sec_mask;
7883
static esp_spp_role_t _role;
7984
// 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
528533
auth_complete_callback(true);
529534
}
530535
} else {
531-
log_e("authentication failed for connecting with \"%s\", status:%d", param->auth_cmpl.device_name, param->auth_cmpl.stat);
536+
log_e("authentication failed, status:%d", param->auth_cmpl.stat);
532537
if (auth_complete_callback) {
533538
auth_complete_callback(false);
534539
}
535540
}
536541
break;
537542
case ESP_BT_GAP_PIN_REQ_EVT: // Enum 5 - Legacy Pairing Pin code request
538-
// default pairing pins
539-
log_i("ESP_BT_GAP_PIN_REQ_EVT min_16_digit:%d", param->pin_req.min_16_digit);
540-
if (param->pin_req.min_16_digit) {
541-
log_i("Input pin code: 0000 0000 0000 0000");
542-
esp_bt_pin_code_t pin_code;
543-
memset(pin_code, '0', ESP_BT_PIN_CODE_LEN);
544-
esp_bt_gap_pin_reply(param->pin_req.bda, true, 16, pin_code);
543+
log_i("ESP_BT_GAP_PIN_REQ_EVT (min_16_digit=%d)", param->pin_req.min_16_digit);
544+
if (param->pin_req.min_16_digit && _pin_code_len < 16) {
545+
esp_bt_gap_pin_reply(param->pin_req.bda, false, 0, NULL);
545546
} else {
546-
log_i("Input pin code: 1234");
547-
esp_bt_pin_code_t pin_code;
548-
memcpy(pin_code, "1234", 4);
549-
esp_bt_gap_pin_reply(param->pin_req.bda, true, 4, pin_code);
547+
//log_i("Input pin code: \"%s\"=0x%x", _pin_code);
548+
log_i("Input pin code: \"%.*s\"=0x%x", _pin_code_len, _pin_code, *(int*)_pin_code);
549+
esp_bt_gap_pin_reply(param->pin_req.bda, true, _pin_code_len, _pin_code);
550550
}
551551
break;
552-
552+
#ifdef CONFIG_BT_SSP_ENABLED
553553
case ESP_BT_GAP_CFM_REQ_EVT: // Enum 6 - Security Simple Pairing User Confirmation request.
554554
log_i("ESP_BT_GAP_CFM_REQ_EVT Please compare the numeric value: %d", param->cfm_req.num_val);
555555
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
561561
esp_bt_gap_ssp_confirm_reply(param->cfm_req.bda, false);
562562
}
563563
break;
564+
#endif
564565

565566
case ESP_BT_GAP_KEY_NOTIF_EVT: // Enum 7 - Security Simple Pairing Passkey Notification
566567
log_i("ESP_BT_GAP_KEY_NOTIF_EVT passkey:%d", param->key_notif.passkey);
567568
break;
568569

570+
#ifdef CONFIG_BT_SSP_ENABLED
569571
case ESP_BT_GAP_KEY_REQ_EVT: // Enum 8 - Security Simple Pairing Passkey request
570572
log_i("ESP_BT_GAP_KEY_REQ_EVT Please enter passkey!");
571573
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
577579
esp_bt_gap_ssp_confirm_reply(param->cfm_req.bda, false);
578580
}
579581
break;
582+
#endif
580583

581584
case ESP_BT_GAP_READ_RSSI_DELTA_EVT: // Enum 9 - Read rssi event
582585
log_i("ESP_BT_GAP_READ_RSSI_DELTA_EVT Read rssi event");
@@ -718,6 +721,7 @@ static bool _init_bt(const char *deviceName)
718721
log_i("device name set");
719722
esp_bt_dev_set_device_name(deviceName);
720723

724+
#ifdef CONFIG_BT_SSP_ENABLED
721725
if (_enableSSP) {
722726
log_i("Simple Secure Pairing");
723727
esp_bt_sp_param_t param_type = ESP_BT_SP_IOCAP_MODE;
@@ -733,6 +737,7 @@ static bool _init_bt(const char *deviceName)
733737
}
734738
esp_bt_gap_set_security_param(param_type, &iocap, sizeof(uint8_t));
735739
}
740+
#endif
736741

737742
// the default BTA_DM_COD_LOUDSPEAKER does not work with the macOS BT stack
738743
esp_bt_cod_t cod;
@@ -908,6 +913,7 @@ void BluetoothSerial::end()
908913
_stop_bt();
909914
}
910915

916+
#ifdef CONFIG_BT_SSP_ENABLED
911917
void BluetoothSerial::onConfirmRequest(ConfirmRequestCb cb)
912918
{
913919
confirm_request_callback = cb;
@@ -921,6 +927,7 @@ void BluetoothSerial::onKeyRequest(KeyRequestCb cb)
921927
void BluetoothSerial::respondPasskey(uint32_t passkey){
922928
esp_bt_gap_ssp_passkey_reply(current_bd_addr, true, passkey);
923929
}
930+
#endif
924931

925932
void BluetoothSerial::onAuthComplete(AuthCompleteCb cb)
926933
{
@@ -939,6 +946,7 @@ esp_err_t BluetoothSerial::register_callback(esp_spp_cb_t * callback)
939946
return ESP_OK;
940947
}
941948

949+
#ifdef CONFIG_BT_SSP_ENABLED
942950
// Enable Simple Secure Pairing (using generated PIN)
943951
// This must be called before calling begin, otherwise has no effect!
944952
void BluetoothSerial::enableSSP() {
@@ -974,6 +982,19 @@ void BluetoothSerial::disableSSP() {
974982
_enableSSP = false;
975983
}
976984

985+
#else
986+
987+
bool BluetoothSerial::setPin(const char *pin, uint8_t pin_code_len){
988+
if(pin_code_len == 0 || pin_code_len > 16){
989+
log_e("PIN code must be 1-16 Bytes long! Called with length %d", pin_code_len);
990+
return false;
991+
}
992+
_pin_code_len = pin_code_len;
993+
memcpy(_pin_code, pin, pin_code_len);
994+
return (esp_bt_gap_set_pin(ESP_BT_PIN_TYPE_FIXED, _pin_code_len, _pin_code) == ESP_OK);
995+
}
996+
#endif
997+
977998
bool BluetoothSerial::connect(String remoteName)
978999
{
9791000
bool retval = false;

0 commit comments

Comments
 (0)