ESP32 не обменивается ключами по BLE
Железяка ESP32-WROOM-32D, framework-arduinoespressif32 == 3.20011.230801. Код на данный момент такой:
#include <Arduino.h>
typedef union Hwid
{
byte data[16];
struct
{
uint32_t chipId;
byte mac[6];
byte mac2[6];
} esp8266;
struct
{
uint32_t chipId;
uint32_t pad;
uint64_t efusemac;
} esp32;
} Hwid;
Hwid get_id()
{
Hwid boardid;
boardid.esp32.efusemac = ESP.getEfuseMac();
for (int i = 0; i < 17; i += 8)
{
boardid.esp32.chipId |= ((boardid.esp32.efusemac >> (40 - i)) & 0xff)
<< i;
}
boardid.esp32.pad = boardid.esp32.chipId;
return boardid;
}
#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>
#include "BLEHIDDevice.h"
#include "HIDTypes.h"
#include "HIDKeyboardTypes.h"
#define SERVICE_UUID "9a8ca9ef-e43f-4157-9fee-c37a3d7dc12d"
#define BLINK_UUID "e94f85c8-7f57-4dbd-b8d3-2b56e107ed60"
#define SPEED_UUID "a8985fda-51aa-4f19-a777-71cf52abba1e"
#define DEVINFO_UUID (uint16_t)0x180a
#define DEVINFO_MANUFACTURER_UUID (uint16_t)0x2a29
#define DEVINFO_NAME_UUID (uint16_t)0x2a24
#define DEVINFO_SERIAL_UUID (uint16_t)0x2a25
#define BATTERY_UUID (uint16_t)0x180F
#define BATTERY_LEVEL_CHARACTERISTIC (uint16_t)0x2A19
#define BATTERY_LEVEL_DECRIPTOR (uint16_t)0x2901
#define DEVICE_MANUFACTURER "Eri"
#define DEVICE_NAME "Kalitka"
#define PIN_BUTTON 0
#define PIN_LED LED_BUILTIN
BLECharacteristic *battChar;
BLEHIDDevice *hid;
BLECharacteristic *input;
BLECharacteristic *output;
uint8_t batt_level = 67;
class MyCallbacks : public BLEServerCallbacks
{
void onConnect(BLEServer *pServer)
{
pServer->startAdvertising();
}
void onDisconnect(BLEServer *pServer)
{
}
};
BLEServer *pServer;
void init_hid(String chipId)
{
const uint8_t report[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
hid = new BLEHIDDevice(pServer);
input = hid->inputReport(1); // <-- input REPORTID from report map
output = hid->outputReport(1); // <-- output REPORTID from report map
hid->manufacturer()->setValue(DEVICE_MANUFACTURER);
hid->manufacturer()->setAccessPermissions(ESP_GATT_PERM_READ_ENCRYPTED);
hid->deviceInfo()->createCharacteristic(DEVINFO_NAME_UUID, BLECharacteristic::PROPERTY_READ)->setValue(DEVICE_NAME);
hid->deviceInfo()->createCharacteristic(DEVINFO_SERIAL_UUID, BLECharacteristic::PROPERTY_READ)->setValue(chipId.c_str());
hid->hidInfo(0x00, 0x01);
hid->reportMap((uint8_t *)report, sizeof(report));
battChar = hid->batteryService()->getCharacteristic(BATTERY_LEVEL_CHARACTERISTIC);
battChar->setAccessPermissions(ESP_GATT_PERM_READ_ENCRYPTED);
hid->startServices();
}
class MySecurity : public BLESecurityCallbacks
{
uint32_t onPassKeyRequest()
{
Serial.printf("PassKeyRequest");
return 434343;
}
void onPassKeyNotify(uint32_t pass_key)
{
Serial.printf("The passkey Notify number:%d", pass_key); //WORKS
}
bool onConfirmPIN(uint32_t pass_key)
{
Serial.printf("The passkey YES/NO number:%d", pass_key);
return true;
}
bool onSecurityRequest()
{
Serial.printf("SecurityRequest");
return true;
}
void onAuthenticationComplete(esp_ble_auth_cmpl_t cmpl)
{
Serial.printf("Starting BLE work!"); //WORKS
if (cmpl.success)
{
Serial.printf("sucess");
Serial.println(cmpl.key_present); // == 0
}
}
};
void setup()
{
Serial.begin(115200);
Serial.println("Starting...");
pinMode(PIN_BUTTON, INPUT);
pinMode(PIN_LED, OUTPUT);
String devName = DEVICE_NAME;
String chipId = String(get_id().esp32.chipId, HEX);
devName += '_';
devName += chipId;
BLEDevice::init(devName.c_str());
BLEDevice::setEncryptionLevel(ESP_BLE_SEC_ENCRYPT);
BLEDevice::setSecurityCallbacks(new MySecurity());
pServer = BLEDevice::createServer();
pServer->setCallbacks(new MyCallbacks());
// devinfo(chipId);
// battery();
init_hid(chipId);
// ----- Advertising
BLEAdvertising *pAdvertising = pServer->getAdvertising();
pAdvertising->setAppearance(ESP_BLE_APPEARANCE_HID_GAMEPAD);
pAdvertising->addServiceUUID(hid->hidService()->getUUID());
pAdvertising->addServiceUUID(hid->batteryService()->getUUID());
BLESecurity *pSecurity = new BLESecurity();
pSecurity->setStaticPIN(434343);
pSecurity->setAuthenticationMode(ESP_LE_AUTH_REQ_SC_BOND);
pServer->startAdvertising();
Serial.println("Ready");
Serial.print("Device name: ");
Serial.println(devName);
}
void printbond()
{
int num = 0;
esp_ble_bond_dev_t *dev_list;
esp_ble_bond_dev_t dev;
esp_bd_addr_t addr;
esp_ble_get_bond_device_list(&num, dev_list);
Serial.print("bonded: ");
Serial.println(num);
if (num == 0)
{
return;
}
num--;
for (; num; num--)
{
dev = dev_list[num];
String s((const uint8_t *)dev.bd_addr, (unsigned int)ESP_BD_ADDR_LEN);
Serial.println(s);
String k((const uint8_t *)dev.bond_key.pcsrk_key.csrk, (unsigned int)ESP_BT_OCTET16_LEN);
Serial.println(k);
}
}
void loop()
{
printbond();
delay(1000);
if (pServer->getConnectedCount() > 0)
{
hid->setBatteryLevel(batt_level);
}
batt_level++;
batt_level %= 101;
// Serial.printf("%d\t", batt_level);
Serial.println(pServer->getConnectedCount());
}
Пинкод запрашивает с андроида, но не передает ключи. С компьютера пинкод не запрашивается. BOND не добавляется на ESP.
esp_ble_get_bond_device_list(&num, dev_list); выдает ноль.
cmpl.key_present выдает ноль
Как решить эту проблему?