#pragma once #include #include #include #include #include #include "esp_err.h" #include "esp_event.h" #include "esp_eth.h" #include "esp_eth_mac.h" #include "esp_eth_netif_glue.h" #include "esp_eth_phy.h" #include "esp_http_server.h" #include "esp_netif.h" #include "esp_now.h" #include "freertos/FreeRTOS.h" #include "freertos/semphr.h" #include "freertos/task.h" #include "gateway_runtime.hpp" #include "lwip/sockets.h" namespace gateway { class GatewayController; class DaliDomainService; class GatewayBridgeService; struct DaliRawFrame; struct GatewayNetworkServiceConfig { bool wifi_enabled{true}; bool ethernet_enabled{false}; bool ethernet_ignore_init_failure{false}; bool espnow_setup_enabled{true}; bool espnow_setup_startup_enabled{false}; bool smartconfig_enabled{true}; bool smartconfig_startup_enabled{false}; uint8_t smartconfig_timeout_sec{60}; bool http_enabled{true}; bool udp_enabled{true}; uint16_t http_port{80}; uint16_t udp_port{2020}; int ethernet_spi_host{1}; int ethernet_spi_sclk_gpio{14}; int ethernet_spi_mosi_gpio{13}; int ethernet_spi_miso_gpio{12}; int ethernet_spi_cs_gpio{15}; int ethernet_spi_int_gpio{4}; uint32_t ethernet_poll_period_ms{0}; uint8_t ethernet_spi_clock_mhz{36}; int ethernet_phy_reset_gpio{5}; int ethernet_phy_addr{1}; uint32_t ethernet_rx_task_stack_size{3072}; int status_led_gpio{-1}; bool status_led_active_high{true}; int boot_button_gpio{-1}; bool boot_button_active_low{true}; uint32_t boot_button_long_press_ms{3000}; uint32_t boot_button_task_stack_size{2048}; UBaseType_t boot_button_task_priority{2}; uint32_t udp_task_stack_size{4096}; UBaseType_t udp_task_priority{4}; }; class GatewayNetworkService { public: GatewayNetworkService(GatewayController& controller, GatewayRuntime& runtime, DaliDomainService& dali_domain, GatewayNetworkServiceConfig config = {}, GatewayBridgeService* bridge_service = nullptr); esp_err_t start(); private: static void UdpTaskEntry(void* arg); static void BootButtonTaskEntry(void* arg); static esp_err_t HandleInfoGet(httpd_req_t* req); static esp_err_t HandleCommandGet(httpd_req_t* req); static esp_err_t HandleCommandPost(httpd_req_t* req); static esp_err_t HandleBridgeGet(httpd_req_t* req); static esp_err_t HandleBridgePost(httpd_req_t* req); static esp_err_t HandleLedOnGet(httpd_req_t* req); static esp_err_t HandleLedOffGet(httpd_req_t* req); static esp_err_t HandleJqJsGet(httpd_req_t* req); static void HandleEthernetEvent(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data); static void HandleWifiEvent(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data); static void HandleEspNowReceive(const esp_now_recv_info_t* info, const uint8_t* data, int data_len); esp_err_t ensureNetworkStack(); esp_err_t startEthernet(); esp_err_t probeEthernetStartup(); void stopEthernet(); esp_err_t startWifi(); esp_err_t startSetupAp(); esp_err_t startSmartconfig(); void stopSmartconfig(); esp_err_t startEspNow(); void stopEspNow(); esp_err_t addEspNowPeer(const uint8_t* mac, bool broadcast = false); esp_err_t sendEspNowJson(const uint8_t* mac, const std::string& payload); esp_err_t configureStatusLed(); esp_err_t startHttpServer(); esp_err_t startUdpTask(); esp_err_t configureBootButton(); esp_err_t startBootButtonTask(); void udpTaskLoop(); void bootButtonTaskLoop(); void handleGatewayNotification(const std::vector& frame); void handleWifiControl(uint8_t mode); void handleEthernetEvent(esp_event_base_t event_base, int32_t event_id, void* event_data); void handleWifiEvent(esp_event_base_t event_base, int32_t event_id, void* event_data); void handleEspNowReceive(const esp_now_recv_info_t* info, const uint8_t* data, int data_len); void handleSetupUartFrame(int setup_id, const std::vector& frame); void handleDaliRawFrame(const DaliRawFrame& frame); std::string deviceInfoJson() const; std::string deviceInfoDoubleEncodedJson() const; std::string gatewaySnapshotJson(); esp_err_t sendBridgeResponse(httpd_req_t* req, bool post); void setStatusLed(bool on); GatewayController& controller_; GatewayRuntime& runtime_; DaliDomainService& dali_domain_; GatewayNetworkServiceConfig config_; GatewayBridgeService* bridge_service_{nullptr}; bool started_{false}; httpd_handle_t http_server_{nullptr}; esp_netif_t* eth_netif_{nullptr}; esp_netif_t* wifi_sta_netif_{nullptr}; esp_netif_t* wifi_ap_netif_{nullptr}; esp_eth_handle_t eth_handle_{nullptr}; esp_eth_mac_t* eth_mac_{nullptr}; esp_eth_phy_t* eth_phy_{nullptr}; esp_eth_netif_glue_handle_t eth_glue_{nullptr}; bool ethernet_started_{false}; bool ethernet_event_handlers_registered_{false}; bool wifi_started_{false}; bool wifi_event_handlers_registered_{false}; bool setup_ap_started_{false}; bool espnow_started_{false}; bool smartconfig_started_{false}; bool smartconfig_event_handler_registered_{false}; std::optional smartconfig_pending_wireless_; bool espnow_connected_{false}; std::array espnow_peer_{}; TaskHandle_t boot_button_task_handle_{nullptr}; TaskHandle_t udp_task_handle_{nullptr}; int udp_socket_{-1}; SemaphoreHandle_t udp_lock_{nullptr}; bool has_udp_remote_{false}; sockaddr_storage udp_remote_addr_{}; socklen_t udp_remote_addr_len_{0}; }; } // namespace gateway