#pragma once #include "bridge_model.hpp" #include "model_value.hpp" #include "esp_err.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include #include #include #include namespace gateway { struct GatewayBacnetServerConfig { uint32_t device_instance{4194303}; std::string device_name{"DALI Gateway"}; std::string local_address; uint16_t udp_port{47808}; uint32_t task_stack_size{8192}; UBaseType_t task_priority{5}; }; struct GatewayBacnetObjectBinding { uint8_t gateway_id{0}; std::string model_id; std::string name; BridgeObjectType object_type{BridgeObjectType::unknown}; uint32_t object_instance{0}; std::string property{"presentValue"}; bool out_of_service{false}; uint32_t reliability{0}; }; struct GatewayBacnetServerStatus { bool started{false}; uint32_t device_instance{0}; uint16_t udp_port{0}; size_t channel_count{0}; size_t object_count{0}; }; using GatewayBacnetWriteCallback = std::function; class GatewayBacnetServer { public: static GatewayBacnetServer& instance(); esp_err_t registerChannel(uint8_t gateway_id, const GatewayBacnetServerConfig& config, std::vector bindings, GatewayBacnetWriteCallback write_callback); GatewayBacnetServerStatus status() const; bool configCompatible(const GatewayBacnetServerConfig& config) const; bool handleWrite(BridgeObjectType object_type, uint32_t object_instance, const DaliValue& value); private: GatewayBacnetServer(); ~GatewayBacnetServer(); GatewayBacnetServer(const GatewayBacnetServer&) = delete; GatewayBacnetServer& operator=(const GatewayBacnetServer&) = delete; struct ChannelRegistration; struct RuntimeBinding; esp_err_t startStackLocked(const GatewayBacnetServerConfig& config); esp_err_t rebuildObjectsLocked(); static void TaskEntry(void* arg); void taskLoop(); GatewayBacnetServerConfig active_config_; std::vector channels_; std::vector runtime_bindings_; mutable SemaphoreHandle_t lock_{nullptr}; TaskHandle_t task_handle_{nullptr}; bool started_{false}; }; } // namespace gateway