how to increase BLE pin length from 6 to 16 characters?
Posted: Fri Oct 02, 2020 9:46 pm
I'm using the below code for BLE and it works great with a hardcoded pin code of 123456.
However, I've not be able to get it to connect with any pin longer than 6 characters. I'd like to use the maximum allowed bluetooth pin length of 16 characters.
I cannot find any documentation on this for ESP32. What am I doing wrong?
[Codebox]
/*
code modified from: https://www.instructables.com/id/ESP32- ... E-AWESOME/
instruction set: https://docs.espressif.com/projects/esp ... _vhci.html
Video: https://www.youtube.com/watch?v=oCMOYS71NIU
Based on Neil Kolban example for IDF: https://github.com/nkolban/ESP32_BLE_Arduino
encryption/security code from: https://groups.google.com/g/mitappinven ... SnILVIAwAJ
detailed info: https://github.com/espressif/esp-idf/bl ... through.md
Ported to Arduino ESP32 by Evandro Copercini
Create a BLE server that, once we receive a connection, will send periodic notifications.
The service advertises itself as: 6E400001-B5A3-F393-E0A9-E50E24DCCA9E
Has a characteristic of: 6E400002-B5A3-F393-E0A9-E50E24DCCA9E - used for receiving data with "WRITE"
Has a characteristic of: 6E400003-B5A3-F393-E0A9-E50E24DCCA9E - used to send data with "NOTIFY"
The design of creating the BLE server is:
1. Create a BLE Server
2. Create a BLE Service
3. Create a BLE Characteristic on the Service
4. Create a BLE Descriptor on the characteristic
5. Start the service.
6. Start advertising.
In this example rxValue is the data received (only accessible inside that function).
And txValue is the data to be sent, in this example just a byte incremented every second.
*/
#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>
#include <BLESecurity.h>
BLECharacteristic *pCharacteristic;
bool deviceConnected = false;
float txValue = 0;
// See the following for generating UUIDs:
// https://www.uuidgenerator.net/
#define SERVICE_UUID "6E400001-B5A3-F393-E0A9-E50E24DCCA9E" // UART service UUID
#define CHARACTERISTIC_UUID_RX "6E400002-B5A3-F393-E0A9-E50E24DCCA9E"
#define CHARACTERISTIC_UUID_TX "6E400003-B5A3-F393-E0A9-E50E24DCCA9E"
class MyServerCallbacks: public BLEServerCallbacks {
void onConnect(BLEServer* pServer) {
deviceConnected = true;
};
void onDisconnect(BLEServer* pServer) {
deviceConnected = false;
}
};
class MySecurity : public BLESecurityCallbacks {
uint32_t onPassKeyRequest() {
ESP_LOGI(LOG_TAG, "PassKeyRequest");
return passkey;
}
void onPassKeyNotify(uint32_t pass_key) {
ESP_LOGI(LOG_TAG, "The passkey Notify number:%d", pass_key);
}
bool onConfirmPIN(uint32_t pass_key) {
ESP_LOGI(LOG_TAG, "The passkey YES/NO number:%d", pass_key);
vTaskDelay(5000);
return true;
}
bool onSecurityRequest() {
ESP_LOGI(LOG_TAG, "SecurityRequest");
return true;
}
void onAuthenticationComplete(esp_ble_auth_cmpl_t cmpl) {
ESP_LOGI(LOG_TAG, "Starting BLE!");
}
};
class MyCallbacks: public BLECharacteristicCallbacks {
void onWrite(BLECharacteristic *pCharacteristic) {
std::string rxValue = pCharacteristic->getValue();
//if data recieved
if (rxValue.length() > 0) {
Serial.print("\nReceived Value: ");
//get it's length
for (int i = 0; i < rxValue.length(); i++) {
Serial.print(rxValue);
}
// Do stuff based on command received by bluetooth
if (rxValue.find("F") != -1) {
MOS1=1;
}
else if (rxValue.find("G") != -1) {
MOS1=0;
}
else if (rxValue.find("H") != -1) {
MOS2=1;
}
}
}
};
void bluetooth_setup(void)
{
// Create the BLE Device String
String blueName = String("Smart_Access_") + getMacAddress();
BLEDevice::init(blueName.c_str()); // Give it a name
// Create the BLE Server
BLEServer *pServer = BLEDevice::createServer();
pServer->setCallbacks(new MyServerCallbacks());
// Create the BLE Service
BLEService *pService = pServer->createService(SERVICE_UUID);
// Enable encryption
BLEDevice::setEncryptionLevel(ESP_BLE_SEC_ENCRYPT);
BLEDevice::setSecurityCallbacks(new MySecurity());
// Create a BLE Characteristic
pCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID_TX,
BLECharacteristic::PROPERTY_NOTIFY
);
pCharacteristic->addDescriptor(new BLE2902());
BLECharacteristic *pCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID_RX,
BLECharacteristic::PROPERTY_WRITE
);
pCharacteristic->setCallbacks(new MyCallbacks());
// Start the service
pService->start();
// Start advertising
pServer->getAdvertising()->start();
Serial.println("\nListening for bluetooth client connection. Will connect automatically if found.");
//generate new passkey
passkey = 123456;
//code for encryption
esp_ble_auth_req_t auth_req = ESP_LE_AUTH_REQ_SC_MITM_BOND; //bonding with peer device after authentication
esp_ble_io_cap_t iocap = ESP_IO_CAP_OUT; //set the IO capability to No output YES input. Otherwise use ESP_IO_CAP_NONE;
uint8_t key_size = 16; //the key size should be 7~16 bytes
uint8_t init_key = ESP_BLE_ENC_KEY_MASK | ESP_BLE_ID_KEY_MASK;
uint8_t rsp_key = ESP_BLE_ENC_KEY_MASK | ESP_BLE_ID_KEY_MASK;
uint8_t auth_option = ESP_BLE_ONLY_ACCEPT_SPECIFIED_AUTH_DISABLE;
// uint8_t oob_support = ESP_BLE_OOB_DISABLE;
esp_ble_gap_set_security_param(ESP_BLE_SM_SET_STATIC_PASSKEY, &passkey, sizeof(uint32_t));
esp_ble_gap_set_security_param(ESP_BLE_SM_AUTHEN_REQ_MODE, &auth_req, sizeof(uint8_t));
esp_ble_gap_set_security_param(ESP_BLE_SM_IOCAP_MODE, &iocap, sizeof(uint8_t));
esp_ble_gap_set_security_param(ESP_BLE_SM_MAX_KEY_SIZE, &key_size, sizeof(uint8_t));
esp_ble_gap_set_security_param(ESP_BLE_SM_ONLY_ACCEPT_SPECIFIED_SEC_AUTH, &auth_option, sizeof(uint8_t));
// esp_ble_gap_set_security_param(ESP_BLE_SM_OOB_SUPPORT, &oob_support, sizeof(uint8_t));
/* If your BLE device act as a Slave, the init_key means you hope which types of key of the master should distribute to you,
and the response key means which key you can distribute to the Master;
If your BLE device act as a master, the response key means you hope which types of key of the slave should distribute to you,
and the init key means which key you can distribute to the slave. */
esp_ble_gap_set_security_param(ESP_BLE_SM_SET_INIT_KEY, &init_key, sizeof(uint8_t));
esp_ble_gap_set_security_param(ESP_BLE_SM_SET_RSP_KEY, &rsp_key, sizeof(uint8_t));
//use max power for max range
//"Default minimum power level is ESP_PWR_LVL_N0, and maximum power level is ESP_PWR_LVL_P9"
esp_err_t errRc=esp_ble_tx_power_set(ESP_BLE_PWR_TYPE_DEFAULT,ESP_PWR_LVL_P9);
esp_ble_tx_power_set(ESP_BLE_PWR_TYPE_ADV, ESP_PWR_LVL_P9);
esp_ble_tx_power_set(ESP_BLE_PWR_TYPE_SCAN ,ESP_PWR_LVL_P9);
Serial.println("\nCharacteristic defined! Now you can read it in your phone!");
}
*/
[/Codebox]
However, I've not be able to get it to connect with any pin longer than 6 characters. I'd like to use the maximum allowed bluetooth pin length of 16 characters.
I cannot find any documentation on this for ESP32. What am I doing wrong?
[Codebox]
/*
code modified from: https://www.instructables.com/id/ESP32- ... E-AWESOME/
instruction set: https://docs.espressif.com/projects/esp ... _vhci.html
Video: https://www.youtube.com/watch?v=oCMOYS71NIU
Based on Neil Kolban example for IDF: https://github.com/nkolban/ESP32_BLE_Arduino
encryption/security code from: https://groups.google.com/g/mitappinven ... SnILVIAwAJ
detailed info: https://github.com/espressif/esp-idf/bl ... through.md
Ported to Arduino ESP32 by Evandro Copercini
Create a BLE server that, once we receive a connection, will send periodic notifications.
The service advertises itself as: 6E400001-B5A3-F393-E0A9-E50E24DCCA9E
Has a characteristic of: 6E400002-B5A3-F393-E0A9-E50E24DCCA9E - used for receiving data with "WRITE"
Has a characteristic of: 6E400003-B5A3-F393-E0A9-E50E24DCCA9E - used to send data with "NOTIFY"
The design of creating the BLE server is:
1. Create a BLE Server
2. Create a BLE Service
3. Create a BLE Characteristic on the Service
4. Create a BLE Descriptor on the characteristic
5. Start the service.
6. Start advertising.
In this example rxValue is the data received (only accessible inside that function).
And txValue is the data to be sent, in this example just a byte incremented every second.
*/
#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>
#include <BLESecurity.h>
BLECharacteristic *pCharacteristic;
bool deviceConnected = false;
float txValue = 0;
// See the following for generating UUIDs:
// https://www.uuidgenerator.net/
#define SERVICE_UUID "6E400001-B5A3-F393-E0A9-E50E24DCCA9E" // UART service UUID
#define CHARACTERISTIC_UUID_RX "6E400002-B5A3-F393-E0A9-E50E24DCCA9E"
#define CHARACTERISTIC_UUID_TX "6E400003-B5A3-F393-E0A9-E50E24DCCA9E"
class MyServerCallbacks: public BLEServerCallbacks {
void onConnect(BLEServer* pServer) {
deviceConnected = true;
};
void onDisconnect(BLEServer* pServer) {
deviceConnected = false;
}
};
class MySecurity : public BLESecurityCallbacks {
uint32_t onPassKeyRequest() {
ESP_LOGI(LOG_TAG, "PassKeyRequest");
return passkey;
}
void onPassKeyNotify(uint32_t pass_key) {
ESP_LOGI(LOG_TAG, "The passkey Notify number:%d", pass_key);
}
bool onConfirmPIN(uint32_t pass_key) {
ESP_LOGI(LOG_TAG, "The passkey YES/NO number:%d", pass_key);
vTaskDelay(5000);
return true;
}
bool onSecurityRequest() {
ESP_LOGI(LOG_TAG, "SecurityRequest");
return true;
}
void onAuthenticationComplete(esp_ble_auth_cmpl_t cmpl) {
ESP_LOGI(LOG_TAG, "Starting BLE!");
}
};
class MyCallbacks: public BLECharacteristicCallbacks {
void onWrite(BLECharacteristic *pCharacteristic) {
std::string rxValue = pCharacteristic->getValue();
//if data recieved
if (rxValue.length() > 0) {
Serial.print("\nReceived Value: ");
//get it's length
for (int i = 0; i < rxValue.length(); i++) {
Serial.print(rxValue);
}
// Do stuff based on command received by bluetooth
if (rxValue.find("F") != -1) {
MOS1=1;
}
else if (rxValue.find("G") != -1) {
MOS1=0;
}
else if (rxValue.find("H") != -1) {
MOS2=1;
}
}
}
};
void bluetooth_setup(void)
{
// Create the BLE Device String
String blueName = String("Smart_Access_") + getMacAddress();
BLEDevice::init(blueName.c_str()); // Give it a name
// Create the BLE Server
BLEServer *pServer = BLEDevice::createServer();
pServer->setCallbacks(new MyServerCallbacks());
// Create the BLE Service
BLEService *pService = pServer->createService(SERVICE_UUID);
// Enable encryption
BLEDevice::setEncryptionLevel(ESP_BLE_SEC_ENCRYPT);
BLEDevice::setSecurityCallbacks(new MySecurity());
// Create a BLE Characteristic
pCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID_TX,
BLECharacteristic::PROPERTY_NOTIFY
);
pCharacteristic->addDescriptor(new BLE2902());
BLECharacteristic *pCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID_RX,
BLECharacteristic::PROPERTY_WRITE
);
pCharacteristic->setCallbacks(new MyCallbacks());
// Start the service
pService->start();
// Start advertising
pServer->getAdvertising()->start();
Serial.println("\nListening for bluetooth client connection. Will connect automatically if found.");
//generate new passkey
passkey = 123456;
//code for encryption
esp_ble_auth_req_t auth_req = ESP_LE_AUTH_REQ_SC_MITM_BOND; //bonding with peer device after authentication
esp_ble_io_cap_t iocap = ESP_IO_CAP_OUT; //set the IO capability to No output YES input. Otherwise use ESP_IO_CAP_NONE;
uint8_t key_size = 16; //the key size should be 7~16 bytes
uint8_t init_key = ESP_BLE_ENC_KEY_MASK | ESP_BLE_ID_KEY_MASK;
uint8_t rsp_key = ESP_BLE_ENC_KEY_MASK | ESP_BLE_ID_KEY_MASK;
uint8_t auth_option = ESP_BLE_ONLY_ACCEPT_SPECIFIED_AUTH_DISABLE;
// uint8_t oob_support = ESP_BLE_OOB_DISABLE;
esp_ble_gap_set_security_param(ESP_BLE_SM_SET_STATIC_PASSKEY, &passkey, sizeof(uint32_t));
esp_ble_gap_set_security_param(ESP_BLE_SM_AUTHEN_REQ_MODE, &auth_req, sizeof(uint8_t));
esp_ble_gap_set_security_param(ESP_BLE_SM_IOCAP_MODE, &iocap, sizeof(uint8_t));
esp_ble_gap_set_security_param(ESP_BLE_SM_MAX_KEY_SIZE, &key_size, sizeof(uint8_t));
esp_ble_gap_set_security_param(ESP_BLE_SM_ONLY_ACCEPT_SPECIFIED_SEC_AUTH, &auth_option, sizeof(uint8_t));
// esp_ble_gap_set_security_param(ESP_BLE_SM_OOB_SUPPORT, &oob_support, sizeof(uint8_t));
/* If your BLE device act as a Slave, the init_key means you hope which types of key of the master should distribute to you,
and the response key means which key you can distribute to the Master;
If your BLE device act as a master, the response key means you hope which types of key of the slave should distribute to you,
and the init key means which key you can distribute to the slave. */
esp_ble_gap_set_security_param(ESP_BLE_SM_SET_INIT_KEY, &init_key, sizeof(uint8_t));
esp_ble_gap_set_security_param(ESP_BLE_SM_SET_RSP_KEY, &rsp_key, sizeof(uint8_t));
//use max power for max range
//"Default minimum power level is ESP_PWR_LVL_N0, and maximum power level is ESP_PWR_LVL_P9"
esp_err_t errRc=esp_ble_tx_power_set(ESP_BLE_PWR_TYPE_DEFAULT,ESP_PWR_LVL_P9);
esp_ble_tx_power_set(ESP_BLE_PWR_TYPE_ADV, ESP_PWR_LVL_P9);
esp_ble_tx_power_set(ESP_BLE_PWR_TYPE_SCAN ,ESP_PWR_LVL_P9);
Serial.println("\nCharacteristic defined! Now you can read it in your phone!");
}
*/
[/Codebox]