#include "NimBLEDevice.h"
#define S_UUID "6E400001-B5A3-F393-E0A9-E50E24DCCA9E"
#define RX_UUID "6E400002-B5A3-F393-E0A9-E50E24DCCA9E"
#define TX_UUID "6E400003-B5A3-F393-E0A9-E50E24DCCA9E"
NimBLECharacteristic* pTX;
bool connected = false;
float lastMeas = 0.0;
class MyTX: public NimBLECharacteristicCallbacks {
    void onRead(NimBLECharacteristic* pC, NimBLEConnInfo& info) override {
        char buf[8];
        dtostrf(lastMeas, 1, 1, buf);
        pC->setValue(buf);
    }
};
class MyRX: public NimBLECharacteristicCallbacks {
    void onWrite(NimBLECharacteristic* pC, NimBLEConnInfo& info) override {
        std::string val = pC->getValue();
        digitalWrite(8, (val.find("A") != -1) ? LOW : HIGH);
    }
};
class MyServer: public NimBLEServerCallbacks {
    void onConnect(NimBLEServer* pS, NimBLEConnInfo& i) override { connected = true; }
    void onDisconnect(NimBLEServer* pS, NimBLEConnInfo& i, int r) override { 
        connected = false; 
        NimBLEDevice::startAdvertising(); 
    }
};
void setup() {
    Serial.begin(115200);
    pinMode(8, OUTPUT); digitalWrite(8, HIGH);
    NimBLEDevice::init("ESP32_BLE_Demo");
    NimBLEServer* pS = NimBLEDevice::createServer();
    pS->setCallbacks(new MyServer());
    NimBLEService* pService = pS->createService(S_UUID);
    pService->createCharacteristic(RX_UUID, NIMBLE_PROPERTY::WRITE)->setCallbacks(new MyRX());
    pTX = pService->createCharacteristic(TX_UUID, NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY);
    pTX->setCallbacks(new MyTX());
    pService->start();
    NimBLEAdvertising* pAdv = NimBLEDevice::getAdvertising();
    NimBLEAdvertisementData advData;
    advData.setFlags(0x06); 
    advData.setName("ESP32_BLE_Demo");
    pAdv->setAdvertisementData(advData);
    NimBLEAdvertisementData scanData;
    scanData.addServiceUUID(NimBLEUUID(S_UUID));
    pAdv->setScanResponseData(scanData);
    pAdv->enableScanResponse(true);   
    pAdv->start();
}
void loop() {
    lastMeas = 25.4; 
    if (connected) {
        char buf[8];
        dtostrf(lastMeas, 1, 1, buf);       
        pTX->setValue(buf); 
        pTX->notify();  
    }
    delay(2000);
}
