Windows 11 mimarisinde Bluetooth LE cihazları eşleştirilirken, işletim sistemi sürücü seviyesinde otomatik doğrulama ("Just Works") yaparak şifre sorma ekranını bypass edebilmektedir. Bu projede, Windows'un otomatik şifre onaylama açıklarını doğrudan ESP32'nin Bluetooth register (kayıtçı) seviyesinde kapatan, kullanıcıyı donanımsal olarak altı haneli sabit şifre (passkey) girmeye mecbur bırakan ve tarama esnasında çift cihaz görünmesini engelleyen kararlı şarj kontrol sistemini ele alıyoruz.
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>
#include <BLE2902.h>
#define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define CHARACTERISTIC_UUID_RX "beb5483e-36e1-4688-b7f5-ea07361b26a8"
#define CHARACTERISTIC_UUID_TX "d2a21e42-cb31-4ee5-bc95-0e6e76cf0e33"
BLEServer* pServer = NULL;
BLECharacteristic* pTxCharacteristic = NULL;
bool cihazBagli = false;
const int voltajPin = 34;
const int akimPin = 35;
const int pwmPin = 25;
const int pwmFrekans = 5000;
const int pwmCozunurluk = 8;
int pwmDuty = 0;
const int filtreKatsayisi = 10;
float voltajDizi[filtreKatsayisi] = {0};
float akimDizi[filtreKatsayisi] = {0};
int filtreIndex = 0;
int aktifMod = 1;
float hedonSarjAkimi = 3.0;
float limitUstVolt = 14.4;
float limitAltVolt = 12.3;
float limitDevamVolt = 13.8;
bool mod1DolduMu = false;
bool mod2BeklemedeMi = false;
String gelenVeri = "";
float gercekVoltajOku() {
int hamDeger = analogRead(voltajPin);
float analogVolt = (hamDeger * 3.3) / 4095.0;
return analogVolt * 5.0;
}
float gercekAkimOku() {
int hamDeger = analogRead(akimPin);
float analogVolt = (hamDeger * 3.3) / 4095.0;
return (analogVolt - 2.5) / 0.066;
}
class YenidirServerCallbacks: public BLEServerCallbacks {
void onConnect(BLEServer* pServer) {
cihazBagli = true;
Serial.println("Sistem: Bir cihaz BLE ile baglandi.");
}
void onDisconnect(BLEServer* pServer) {
cihazBagli = false;
Serial.println("Sistem: Cihaz baglantisi kesildi. Tekrar yayin yapiliyor...");
pServer->getAdvertising()->start();
}
};
class KomutYakalayici: public BLECharacteristicCallbacks {
void onWrite(BLECharacteristic *pCharacteristic) {
String rxDeger = pCharacteristic->getValue();
if (rxDeger.length() > 0) {
gelenVeri = rxDeger;
gelenVeri.trim();
Serial.print("BLE'den Gelen: "); Serial.println(gelenVeri);
}
}
};
class BLEGuvenlikYoneticisi : public BLESecurityCallbacks {
uint32_t onPassKeyRequest() {
Serial.println("BLE Donanim Guvenligi: Passkey talep edildi!");
return 123456;
}
void onPassKeyNotify(uint32_t pass_key) {
Serial.print("BLE Donanim Guvenligi: Ekranda gosterilmesi gereken PIN: ");
Serial.println(pass_key);
}
bool onSecurityRequest() {
return true;
}
void onAuthenticationComplete(esp_ble_auth_cmpl_t cmpl) {
if (cmpl.success) {
Serial.println("BLE Donanim Guvenligi: DONANIMSAL ESLESME BASARILI!");
} else {
Serial.println("BLE Donanim Guvenligi: DONANIMSAL SIFRE HATALI VEYA REDDEDILDI!");
}
}
};
void setup() {
Serial.begin(115200);
BLEDevice::init("Yenidir_BMS_BLE");
BLEDevice::setSecurityCallbacks(new BLEGuvenlikYoneticisi());
pServer = BLEDevice::createServer();
pServer->setCallbacks(new YenidirServerCallbacks());
BLEService *pService = pServer->createService(SERVICE_UUID);
pTxCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID_TX,
BLECharacteristic::PROPERTY_READ |
BLECharacteristic::PROPERTY_NOTIFY |
BLECharacteristic::PROPERTY_READ_ENC
);
pTxCharacteristic->addDescriptor(new BLE2902());
BLECharacteristic *pRxCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID_RX,
BLECharacteristic::PROPERTY_WRITE |
BLECharacteristic::PROPERTY_WRITE_ENC
);
pRxCharacteristic->setCallbacks(new KomutYakalayici());
pService->start();
BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
pAdvertising->addServiceUUID(SERVICE_UUID);
pAdvertising->setScanResponse(false);
BLESecurity *pSecurity = new BLESecurity();
pSecurity->setAuthenticationMode(ESP_LE_AUTH_BOND);
pSecurity->setCapability(ESP_IO_CAP_OUT);
pSecurity->setInitEncryptionKey(ESP_BLE_ENC_KEY_MASK | ESP_BLE_ID_KEY_MASK);
uint32_t sabitSifre = 123456;
esp_ble_gap_set_security_param(ESP_BLE_SM_SET_STATIC_PASSKEY, &sabitSifre, sizeof(uint32_t));
BLEDevice::startAdvertising();
Serial.println("Yenidir BMS Baslatildi. Donanimsal Kilit Kodu 123456 olarak sabitlendi!");
ledcAttach(pwmPin, pwmFrekans, pwmCozunurluk);
}
void loop() {
if (gelenVeri != "") {
if (gelenVeri.startsWith("MOD:")) {
aktifMod = gelenVeri.substring(4).toInt();
mod1DolduMu = false; mod2BeklemedeMi = false; pwmDuty = 0;
Serial.print("Sistem: MOD DEGISTI -> "); Serial.println(aktifMod);
}
else if (gelenVeri.startsWith("AKIM:")) {
hedonSarjAkimi = gelenVeri.substring(5).toFloat();
}
else if (gelenVeri.startsWith("UST:")) {
limitUstVolt = gelenVeri.substring(4).toFloat();
}
else if (gelenVeri.startsWith("ALT:")) {
limitAltVolt = gelenVeri.substring(4).toFloat();
}
else if (gelenVeri.startsWith("DEVAM:")) {
limitDevamVolt = gelenVeri.substring(6).toFloat();
}
gelenVeri = "";
}
voltajDizi[filtreIndex] = gercekVoltajOku();
akimDizi[filtreIndex] = gercekAkimOku();
filtreIndex = (filtreIndex + 1) % filtreKatsayisi;
float filtreliVolt = 0; float filtreliAkim = 0;
for (int i = 0; i < filtreKatsayisi; i++) {
filtreliVolt += voltajDizi[i]; filtreliAkim += akimDizi[i];
}
filtreliVolt /= filtreKatsayisi; filtreliAkim /= filtreKatsayisi;
if (aktifMod == 1) {
if (!mod1DolduMu) {
if (filtreliVolt >= limitUstVolt) mod1DolduMu = true;
else {
if (filtreliAkim < hedonSarjAkimi && pwmDuty < 255) pwmDuty++;
if (filtreliAkim > hedonSarjAkimi && pwmDuty > 0) pwmDuty--;
}
} else {
if (filtreliVolt < limitDevamVolt && pwmDuty < 255) pwmDuty++;
if (filtreliVolt > limitDevamVolt && pwmDuty > 0) pwmDuty--;
}
}
else if (aktifMod == 2) {
if (!mod2BeklemedeMi) {
if (filtreliVolt >= limitUstVolt) { mod2BeklemedeMi = true; pwmDuty = 0; }
else {
if (filtreliAkim < hedonSarjAkimi && pwmDuty < 255) pwmDuty++;
if (filtreliAkim > hedonSarjAkimi && pwmDuty > 0) pwmDuty--;
}
} else {
pwmDuty = 0;
if (filtreliVolt <= limitAltVolt) mod2BeklemedeMi = false;
}
}
else if (aktifMod == 3) {
if (filtreliVolt < limitDevamVolt && pwmDuty < 255) pwmDuty++;
if (filtreliVolt > limitDevamVolt && pwmDuty > 0) pwmDuty--;
}
ledcWrite(pwmPin, pwmDuty);
static unsigned long sonRaporZamani = 0;
if (millis() - sonRaporZamani >= 2000) {
sonRaporZamani = millis();
String rapor = "V:" + String(filtreliVolt, 2) +
" A:" + String(filtreliAkim, 2) +
" M:" + String(aktifMod) +
" P:" + String(pwmDuty) + "\n";
Serial.print(rapor);
if (cihazBagli) {
pTxCharacteristic->setValue(rapor.c_str());
pTxCharacteristic->notify();
}
}
delay(10);
}
Henüz yorum yapılmamış. İlk yorumu siz yapın!