#pragma once #include #include #include #include #include "comm_base.hpp" #include "event_bus.hpp" #include "topic.hpp" class BluetoothService : public CommBase<> { BLEServer* bleServer {nullptr}; BLECharacteristic* txCharacteristic {nullptr}; BLECharacteristic* rxCharacteristic {nullptr}; bool connected {false}; protected: template using EventBusHandle = typename EventBus::Handle; template EventBusHandle& getHandle(Topic topic) { return *static_cast*>(subscriptionHandle[static_cast(topic)]); } template void setHandle(Topic topic, EventBusHandle&& handle) { subscriptionHandle[static_cast(topic)] = new EventBusHandle(std::move(handle)); } std::array(Topic::COUNT)> subscriptionHandle {}; private: void handleReceive(const std::string& data); void send(size_t clientId, const char* data, size_t len) override; struct ServerCb : BLEServerCallbacks { BluetoothService* svc; ServerCb(BluetoothService* s) : svc(s) {} void onConnect(BLEServer*) override { svc->connected = true; } void onDisconnect(BLEServer* s) override { svc->connected = false; for (size_t i = 0; i < static_cast(Topic::COUNT); ++i) svc->unsubscribe(static_cast(i), 0); svc->bleServer->startAdvertising(); } }; struct RxCb : BLECharacteristicCallbacks { BluetoothService* svc; RxCb(BluetoothService* s) : svc(s) {} void onWrite(BLECharacteristic* c) override { auto v = c->getValue(); if (!v.empty()) svc->handleReceive(v); } }; public: void begin(const char* name); void loop() {} };