BluetoothSerial SSP Authentication with callbacks (#4634)
Added authentication callbacks and example, resolves #4622.
This commit is contained in:
parent
434d02c49f
commit
81b9130d8d
@ -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);
|
||||||
|
}
|
||||||
|
}
|
@ -51,6 +51,9 @@ static EventGroupHandle_t _spp_event_group = NULL;
|
|||||||
static boolean secondConnectionAttempt;
|
static boolean secondConnectionAttempt;
|
||||||
static esp_spp_cb_t * custom_spp_callback = NULL;
|
static esp_spp_cb_t * custom_spp_callback = NULL;
|
||||||
static BluetoothSerialDataCb custom_data_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_LEN 0x10
|
||||||
#define INQ_NUM_RSPS 20
|
#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:
|
case ESP_BT_GAP_AUTH_CMPL_EVT:
|
||||||
if (param->auth_cmpl.stat == ESP_BT_STATUS_SUCCESS) {
|
if (param->auth_cmpl.stat == ESP_BT_STATUS_SUCCESS) {
|
||||||
log_v("authentication success: %s", param->auth_cmpl.device_name);
|
log_v("authentication success: %s", param->auth_cmpl.device_name);
|
||||||
|
if (auth_complete_callback) {
|
||||||
|
auth_complete_callback(true);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
log_e("authentication failed, status:%d", param->auth_cmpl.stat);
|
log_e("authentication failed, status:%d", param->auth_cmpl.stat);
|
||||||
|
if (auth_complete_callback) {
|
||||||
|
auth_complete_callback(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
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:
|
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);
|
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;
|
break;
|
||||||
|
|
||||||
case ESP_BT_GAP_KEY_NOTIF_EVT:
|
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");
|
log_e("gap register failed");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -672,6 +689,22 @@ void BluetoothSerial::end()
|
|||||||
_stop_bt();
|
_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)
|
esp_err_t BluetoothSerial::register_callback(esp_spp_cb_t * callback)
|
||||||
{
|
{
|
||||||
custom_spp_callback = callback;
|
custom_spp_callback = callback;
|
||||||
|
@ -25,6 +25,8 @@
|
|||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
typedef std::function<void(const uint8_t *buffer, size_t size)> BluetoothSerialDataCb;
|
typedef std::function<void(const uint8_t *buffer, size_t size)> BluetoothSerialDataCb;
|
||||||
|
typedef std::function<void(uint32_t num_val)> ConfirmRequestCb;
|
||||||
|
typedef std::function<void(boolean success)> AuthCompleteCb;
|
||||||
|
|
||||||
class BluetoothSerial: public Stream
|
class BluetoothSerial: public Stream
|
||||||
{
|
{
|
||||||
@ -44,6 +46,10 @@ class BluetoothSerial: public Stream
|
|||||||
void end(void);
|
void end(void);
|
||||||
void onData(BluetoothSerialDataCb cb);
|
void onData(BluetoothSerialDataCb cb);
|
||||||
esp_err_t register_callback(esp_spp_cb_t * callback);
|
esp_err_t register_callback(esp_spp_cb_t * callback);
|
||||||
|
|
||||||
|
void onConfirmRequest(ConfirmRequestCb cb);
|
||||||
|
void onAuthComplete(AuthCompleteCb cb);
|
||||||
|
void confirmReply(boolean confirm);
|
||||||
|
|
||||||
void enableSSP();
|
void enableSSP();
|
||||||
bool setPin(const char *pin);
|
bool setPin(const char *pin);
|
||||||
|
Loading…
Reference in New Issue
Block a user