#pragma once #include #include #include #include #include #include #include #include #include #include "esp_err.h" #include "freertos/FreeRTOS.h" #include "freertos/semphr.h" #include "gateway_core.hpp" #include "nvs.h" namespace gateway { esp_err_t InitializeRuntimeNvs(); std::string ReadRuntimeSerialId(); class DaliDomainService; struct WirelessInfo { std::string ssid; std::string password; std::string mac; std::string ip; }; struct GatewayRuntimeConfig { std::string_view project_name; std::string_view version; std::string serial_id; bool default_ble_enabled{true}; bool default_cache_enabled{true}; size_t command_queue_capacity{16}; }; struct GatewayDeviceInfo { std::string serial_id; std::string type; std::string project; std::string version; size_t dali_gateway_count{0}; bool ble_enabled{false}; std::optional wlan; }; class GatewaySettingsStore { public: GatewaySettingsStore(); ~GatewaySettingsStore(); esp_err_t open(); void close(); bool getBleEnabled(bool default_value = false) const; bool setBleEnabled(bool enabled); bool getCacheEnabled(bool default_value = true) const; bool setCacheEnabled(bool enabled); std::optional getWifiSsid() const; std::optional getWifiPassword() const; bool setWifiCredentials(std::string_view ssid, std::string_view password); bool clearWifiCredentials(); std::string getGatewayName(uint8_t gateway_id, std::string_view fallback) const; bool setGatewayName(uint8_t gateway_id, std::string_view name); private: std::optional readString(std::string_view key) const; bool writeString(std::string_view key, std::string_view value); std::string makeGatewayNameKey(uint8_t gateway_id) const; mutable nvs_handle_t handle_{0}; }; class GatewayRuntime { public: enum class CommandDropReason { kNone, kDuplicate, kQueueFull, }; enum class CommandPriority : uint8_t { kControl = 0, kNormal = 1, kMaintenance = 2, }; GatewayRuntime(BootProfile profile, GatewayRuntimeConfig config, DaliDomainService* dali_domain); ~GatewayRuntime(); esp_err_t start(); static std::vector checksum(std::vector frame); static bool hasValidChecksum(const std::vector& frame); static bool isGatewayCommandFrame(const std::vector& frame); static std::vector buildNotificationFrame(const std::vector& payload); static CommandPriority classifyCommandPriority(const std::vector& command); bool enqueueCommand(std::vector command, CommandPriority priority = CommandPriority::kNormal); std::optional> popNextCommand(); void completeCurrentCommand(); bool hasPendingQueryCommand(const std::vector& command) const; bool hasPendingControlCommand(uint8_t gateway_id) const; bool shouldYieldMaintenance(uint8_t gateway_id) const; bool hasActiveCommand(uint8_t gateway_id) const; bool hasActiveQueryCommand(uint8_t gateway_id) const; CommandDropReason lastEnqueueDropReason() const; void setGatewayCount(size_t gateway_count); void setWirelessInfo(WirelessInfo info); bool clearWirelessInfo(); void setCommandAddressResolver(std::function resolver); GatewayDeviceInfo deviceInfo() const; bool bleEnabled() const; bool setBleEnabled(bool enabled); bool cacheEnabled() const; bool setCacheEnabled(bool enabled); std::string gatewayName(uint8_t gateway_id) const; bool setGatewayName(uint8_t gateway_id, std::string_view name); std::string gatewaySerialHex(uint8_t gateway_id) const; std::string bleMacHex() const; std::string bleGatewayName(uint8_t gateway_id, std::string_view gateway_name) const; std::string defaultBleGatewayName() const; private: bool isQueryCommand(const std::vector& command) const; size_t pendingCommandCountLocked() const; std::deque>& queueForPriorityLocked(CommandPriority priority); const std::deque>& queueForPriorityLocked(CommandPriority priority) const; std::optional queryCommandKey(const std::vector& command) const; std::string defaultGatewayName(uint8_t gateway_id) const; std::vector serialBytes() const; static std::string toHex(const std::vector& bytes); BootProfile profile_; GatewayRuntimeConfig config_; DaliDomainService* dali_domain_; GatewaySettingsStore settings_; std::optional> current_command_; CommandPriority current_command_priority_{CommandPriority::kNormal}; std::deque> control_commands_; std::deque> normal_commands_; std::deque> maintenance_commands_; mutable std::map gateway_names_; size_t gateway_count_{0}; bool ble_enabled_{false}; bool cache_enabled_{true}; CommandDropReason last_enqueue_drop_reason_{CommandDropReason::kNone}; std::function command_address_resolver_; std::optional wireless_info_; SemaphoreHandle_t command_lock_{nullptr}; }; } // namespace gateway