feat: add KNX gateway snapshot and command transaction handling

Signed-off-by: Tony <tonylu@tony-cloud.com>
This commit is contained in:
Tony
2026-06-13 01:47:36 +08:00
parent 40a0e8e303
commit be9ff9c2c9
8 changed files with 527 additions and 6 deletions
@@ -65,6 +65,19 @@ struct GatewayControllerSnapshot {
std::vector<GatewayChannelSnapshot> channels;
};
enum class GatewayCommandTransactionStatus : uint8_t {
kOk = 0,
kInvalidFrame = 1,
kQueueRejected = 2,
kTimeout = 3,
kNoResponse = 4,
};
struct GatewayCommandTransactionResult {
GatewayCommandTransactionStatus status{GatewayCommandTransactionStatus::kNoResponse};
std::vector<uint8_t> frames;
};
class GatewayController {
public:
using NotificationSink = std::function<void(const std::vector<uint8_t>& frame)>;
@@ -79,6 +92,11 @@ class GatewayController {
esp_err_t start();
bool enqueueCommandFrame(const std::vector<uint8_t>& frame);
GatewayCommandTransactionResult transactCommandFrame(
const std::vector<uint8_t>& frame,
uint32_t timeout_ms = 700,
uint32_t idle_ms = 30,
size_t max_response_bytes = 2048);
void addNotificationSink(NotificationSink sink);
void addBleStateSink(BleStateSink sink);
void addWifiStateSink(WifiStateSink sink);
@@ -122,6 +140,15 @@ class GatewayController {
uint8_t short_address{0};
};
struct TransactionWaiter {
uint8_t gateway_id{0};
uint8_t opcode{0};
SemaphoreHandle_t signal{nullptr};
std::vector<uint8_t> frames;
size_t max_response_bytes{0};
bool overflow{false};
};
static void TaskEntry(void* arg);
void taskLoop();
void dispatchCommand(const std::vector<uint8_t>& command);
@@ -144,6 +171,9 @@ class GatewayController {
void refreshRuntimeGatewayNames();
void publishPayload(uint8_t gateway_id, const std::vector<uint8_t>& payload);
void publishFrame(const std::vector<uint8_t>& frame);
bool transactionFrameMatches(const TransactionWaiter& waiter,
const std::vector<uint8_t>& frame) const;
void captureTransactionFrame(const std::vector<uint8_t>& frame);
void handleDaliRawFrame(const DaliRawFrame& frame);
bool handleApplicationControllerFrame(const DaliRawFrame& frame);
std::optional<uint8_t> applicationControllerResponse(uint8_t gateway_id, uint8_t first,
@@ -203,11 +233,13 @@ class GatewayController {
GatewayControllerConfig config_;
TaskHandle_t task_handle_{nullptr};
SemaphoreHandle_t maintenance_lock_{nullptr};
SemaphoreHandle_t transaction_lock_{nullptr};
std::vector<NotificationSink> notification_sinks_;
std::vector<BleStateSink> ble_state_sinks_;
std::vector<WifiStateSink> wifi_state_sinks_;
std::vector<GatewayNameSink> gateway_name_sinks_;
std::map<uint16_t, BridgeTransportRequestState> bridge_transport_requests_;
std::vector<TransactionWaiter*> transaction_waiters_;
std::map<uint8_t, ReconciliationJob> reconciliation_jobs_;
std::map<uint8_t, CacheRefreshJob> cache_refresh_jobs_;
std::atomic<int> maintenance_activity_gateway_{-1};