From 81b9130d8d714349c54394b316ed781d0adad456 Mon Sep 17 00:00:00 2001 From: richardclli Date: Mon, 11 Jan 2021 17:58:15 +0800 Subject: [PATCH] BluetoothSerial SSP Authentication with callbacks (#4634) Added authentication callbacks and example, resolves #4622. --- .../SerialToSerialBT_SSP_pairing.ino | 75 +++++++++++++++++++ .../BluetoothSerial/src/BluetoothSerial.cpp | 37 ++++++++- .../BluetoothSerial/src/BluetoothSerial.h | 6 ++ 3 files changed, 116 insertions(+), 2 deletions(-) create mode 100644 libraries/BluetoothSerial/examples/SerialToSerialBT_SSP_pairing/SerialToSerialBT_SSP_pairing.ino diff --git a/libraries/BluetoothSerial/examples/SerialToSerialBT_SSP_pairing/SerialToSerialBT_SSP_pairing.ino b/libraries/BluetoothSerial/examples/SerialToSerialBT_SSP_pairing/SerialToSerialBT_SSP_pairing.ino new file mode 100644 index 00000000..8791b6c7 --- /dev/null +++ b/libraries/BluetoothSerial/examples/SerialToSerialBT_SSP_pairing/SerialToSerialBT_SSP_pairing.ino @@ -0,0 +1,75 @@ +//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 + +#include "BluetoothSerial.h" + +#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED) +#error Bluetooth is not enabled! Please run `make menuconfig` to and enable it +#endif + +BluetoothSerial SerialBT; +boolean confirmRequestPending = true; + +void BTConfirmRequestCallback(uint32_t numVal) +{ + confirmRequestPending = true; + Serial.println(numVal); +} + +void BTAuthCompleteCallback(boolean success) +{ + confirmRequestPending = false; + if (success) + { + Serial.println("Pairing success!!"); + } + else + { + Serial.println("Pairing failed, rejected by user!!"); + } +} + + +void setup() +{ + Serial.begin(115200); + 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!"); +} + +void loop() +{ + if (confirmRequestPending) + { + if (Serial.available()) + { + int dat = Serial.read(); + if (dat == 'Y' || dat == 'y') + { + SerialBT.confirmReply(true); + } + else + { + SerialBT.confirmReply(false); + } + } + } + else + { + if (Serial.available()) + { + SerialBT.write(Serial.read()); + } + if (SerialBT.available()) + { + Serial.write(SerialBT.read()); + } + delay(20); + } +} diff --git a/libraries/BluetoothSerial/src/BluetoothSerial.cpp b/libraries/BluetoothSerial/src/BluetoothSerial.cpp index a52e48d8..c9c494a4 100755 --- a/libraries/BluetoothSerial/src/BluetoothSerial.cpp +++ b/libraries/BluetoothSerial/src/BluetoothSerial.cpp @@ -51,6 +51,9 @@ static EventGroupHandle_t _spp_event_group = NULL; static boolean secondConnectionAttempt; 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 AuthCompleteCb auth_complete_callback = NULL; #define INQ_LEN 0x10 #define INQ_NUM_RSPS 20 @@ -398,8 +401,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_AUTH_CMPL_EVT: if (param->auth_cmpl.stat == ESP_BT_STATUS_SUCCESS) { log_v("authentication success: %s", param->auth_cmpl.device_name); + if (auth_complete_callback) { + auth_complete_callback(true); + } } else { log_e("authentication failed, status:%d", param->auth_cmpl.stat); + if (auth_complete_callback) { + auth_complete_callback(false); + } } break; @@ -421,7 +430,13 @@ static void esp_bt_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *pa case ESP_BT_GAP_CFM_REQ_EVT: log_i("ESP_BT_GAP_CFM_REQ_EVT Please compare the numeric value: %d", param->cfm_req.num_val); - esp_bt_gap_ssp_confirm_reply(param->cfm_req.bda, true); + if (confirm_request_callback) { + memcpy(current_bd_addr, param->cfm_req.bda, sizeof(esp_bd_addr_t)); + confirm_request_callback(param->cfm_req.num_val); + } + else { + esp_bt_gap_ssp_confirm_reply(param->cfm_req.bda, true); + } break; case ESP_BT_GAP_KEY_NOTIF_EVT: @@ -500,7 +515,9 @@ static bool _init_bt(const char *deviceName) } } - if (_isMaster && esp_bt_gap_register_callback(esp_bt_gap_cb) != ESP_OK) { + // Why only master need this? Slave need this during pairing as well +// if (_isMaster && esp_bt_gap_register_callback(esp_bt_gap_cb) != ESP_OK) { + if (esp_bt_gap_register_callback(esp_bt_gap_cb) != ESP_OK) { log_e("gap register failed"); return false; } @@ -672,6 +689,22 @@ void BluetoothSerial::end() _stop_bt(); } +void BluetoothSerial::onConfirmRequest(ConfirmRequestCb cb) +{ + confirm_request_callback = cb; +} + +void BluetoothSerial::onAuthComplete(AuthCompleteCb cb) +{ + auth_complete_callback = cb; +} + +void BluetoothSerial::confirmReply(boolean confirm) +{ + esp_bt_gap_ssp_confirm_reply(current_bd_addr, confirm); +} + + esp_err_t BluetoothSerial::register_callback(esp_spp_cb_t * callback) { custom_spp_callback = callback; diff --git a/libraries/BluetoothSerial/src/BluetoothSerial.h b/libraries/BluetoothSerial/src/BluetoothSerial.h index 6ccb9b49..04dbcb17 100755 --- a/libraries/BluetoothSerial/src/BluetoothSerial.h +++ b/libraries/BluetoothSerial/src/BluetoothSerial.h @@ -25,6 +25,8 @@ #include typedef std::function BluetoothSerialDataCb; +typedef std::function ConfirmRequestCb; +typedef std::function AuthCompleteCb; class BluetoothSerial: public Stream { @@ -44,6 +46,10 @@ class BluetoothSerial: public Stream void end(void); void onData(BluetoothSerialDataCb cb); esp_err_t register_callback(esp_spp_cb_t * callback); + + void onConfirmRequest(ConfirmRequestCb cb); + void onAuthComplete(AuthCompleteCb cb); + void confirmReply(boolean confirm); void enableSSP(); bool setPin(const char *pin);