#pragma once #include "decode.hpp" #include #include #include #include enum class BusDir { front, back }; enum class BusFrameSource { local, external }; struct BusFrame { BusDir dir = BusDir::front; int proto = 0x10; int b1 = 0; int b2 = 0; int b3 = -1; int gateway = -1; BusFrameSource source = BusFrameSource::local; }; class BusMonitor { public: static BusMonitor& I() { static BusMonitor inst; return inst; } void setResponseWindowMs(int ms) { decoder.responseWindowMs = ms; } void setRawSink(std::function sink) { rawSink_ = std::move(sink); } void setDecodedSink(std::function sink) { decodedSink_ = std::move(sink); } void emitFront(int proto, int addr, int cmd, int gateway = -1, BusFrameSource source = BusFrameSource::local) { BusFrame f{BusDir::front, proto, addr & 0xFF, cmd & 0xFF, -1, gateway, source}; rawFrames.push_back(f); if (rawSink_) rawSink_(f); auto rec = decoder.decode(addr & 0xFF, cmd & 0xFF, proto, gateway, sourceName(source)); records.push_back(rec); if (decodedSink_) decodedSink_(rec); } void emitBack(int value, int prefix = 0xFF, int gateway = -1, BusFrameSource source = BusFrameSource::local) { BusFrame f{BusDir::back, 0xFF, prefix & 0xFF, value & 0xFF, -1, gateway, source}; rawFrames.push_back(f); if (rawSink_) rawSink_(f); auto rec = decoder.decodeCmdResponse(value & 0xFF, prefix & 0xFF, gateway, sourceName(source)); records.push_back(rec); if (decodedSink_) decodedSink_(rec); } void clear() { rawFrames.clear(); records.clear(); } void dispose() { rawFrames.clear(); records.clear(); rawSink_ = nullptr; decodedSink_ = nullptr; } DaliDecode decoder; std::vector rawFrames; std::vector records; private: BusMonitor() = default; static std::string sourceName(BusFrameSource source) { return source == BusFrameSource::external ? "external" : "local"; } std::function rawSink_; std::function decodedSink_; };