feat(gateway): add GatewayNetworkService and enhance runtime channel handling
Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
idf_component_register(
|
||||
SRCS "app_main.cpp"
|
||||
REQUIRES gateway_core gateway_controller dali_domain gateway_runtime gateway_ble log
|
||||
REQUIRES gateway_core gateway_controller gateway_network dali_domain gateway_runtime gateway_ble log
|
||||
)
|
||||
|
||||
set_property(TARGET ${COMPONENT_LIB} PROPERTY CXX_STANDARD 17)
|
||||
@@ -98,6 +98,18 @@ config GATEWAY_CHANNEL1_SERIAL_RX_BUFFER
|
||||
range 128 4096
|
||||
default 512
|
||||
|
||||
config GATEWAY_CHANNEL1_SERIAL_TX_BUFFER
|
||||
int "Serial PHY TX buffer bytes"
|
||||
depends on GATEWAY_CHANNEL1_PHY_UART1 || GATEWAY_CHANNEL1_PHY_UART2
|
||||
range 0 4096
|
||||
default 512
|
||||
|
||||
config GATEWAY_CHANNEL1_SERIAL_QUERY_TIMEOUT_MS
|
||||
int "Serial PHY query timeout ms"
|
||||
depends on GATEWAY_CHANNEL1_PHY_UART1 || GATEWAY_CHANNEL1_PHY_UART2
|
||||
range 10 5000
|
||||
default 500
|
||||
|
||||
endmenu
|
||||
|
||||
menu "Gateway Channel 2"
|
||||
@@ -193,6 +205,18 @@ config GATEWAY_CHANNEL2_SERIAL_RX_BUFFER
|
||||
range 128 4096
|
||||
default 512
|
||||
|
||||
config GATEWAY_CHANNEL2_SERIAL_TX_BUFFER
|
||||
int "Serial PHY TX buffer bytes"
|
||||
depends on GATEWAY_CHANNEL_COUNT >= 2 && (GATEWAY_CHANNEL2_PHY_UART1 || GATEWAY_CHANNEL2_PHY_UART2)
|
||||
range 0 4096
|
||||
default 512
|
||||
|
||||
config GATEWAY_CHANNEL2_SERIAL_QUERY_TIMEOUT_MS
|
||||
int "Serial PHY query timeout ms"
|
||||
depends on GATEWAY_CHANNEL_COUNT >= 2 && (GATEWAY_CHANNEL2_PHY_UART1 || GATEWAY_CHANNEL2_PHY_UART2)
|
||||
range 10 5000
|
||||
default 500
|
||||
|
||||
endmenu
|
||||
|
||||
config GATEWAY_ENABLE_DALI_BUS
|
||||
|
||||
@@ -2,11 +2,14 @@
|
||||
#include "gateway_ble.hpp"
|
||||
#include "gateway_controller.hpp"
|
||||
#include "gateway_core.hpp"
|
||||
#include "gateway_network.hpp"
|
||||
#include "gateway_runtime.hpp"
|
||||
|
||||
#include "esp_log.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
|
||||
#ifndef CONFIG_GATEWAY_CHANNEL_COUNT
|
||||
@@ -16,10 +19,12 @@
|
||||
namespace {
|
||||
constexpr const char* kProjectName = "DALI_485_Gateway";
|
||||
constexpr const char* kProjectVersion = "0.1.0";
|
||||
constexpr const char* kTag = "gateway_main";
|
||||
|
||||
std::unique_ptr<gateway::DaliDomainService> s_dali_domain;
|
||||
std::unique_ptr<gateway::GatewayRuntime> s_runtime;
|
||||
std::unique_ptr<gateway::GatewayController> s_controller;
|
||||
std::unique_ptr<gateway::GatewayNetworkService> s_network;
|
||||
std::unique_ptr<gateway::GatewayBleBridge> s_ble_bridge;
|
||||
|
||||
[[maybe_unused]] void LogBindError(const char* channel_name, esp_err_t err) {
|
||||
@@ -28,8 +33,111 @@ std::unique_ptr<gateway::GatewayBleBridge> s_ble_bridge;
|
||||
}
|
||||
}
|
||||
|
||||
void BindConfiguredChannels(gateway::DaliDomainService& dali_domain,
|
||||
const gateway::GatewayRuntime& runtime) {
|
||||
struct ChannelBindingConfig {
|
||||
bool enabled{false};
|
||||
bool native_phy{false};
|
||||
bool serial_phy{false};
|
||||
uint8_t gateway_id{0};
|
||||
uint8_t native_bus_id{0};
|
||||
uint32_t native_baudrate{0};
|
||||
int uart_port{-1};
|
||||
};
|
||||
|
||||
bool ValidateChannelBindings() {
|
||||
ChannelBindingConfig channels[CONFIG_GATEWAY_CHANNEL_COUNT] = {};
|
||||
|
||||
#if CONFIG_GATEWAY_CHANNEL1_PHY_NATIVE
|
||||
channels[0].enabled = true;
|
||||
channels[0].native_phy = true;
|
||||
channels[0].gateway_id = static_cast<uint8_t>(CONFIG_GATEWAY_CHANNEL1_GW_ID);
|
||||
channels[0].native_bus_id = static_cast<uint8_t>(CONFIG_GATEWAY_CHANNEL1_NATIVE_BUS_ID);
|
||||
channels[0].native_baudrate = static_cast<uint32_t>(CONFIG_GATEWAY_CHANNEL1_NATIVE_BAUDRATE);
|
||||
#elif CONFIG_GATEWAY_CHANNEL1_PHY_UART1
|
||||
channels[0].enabled = true;
|
||||
channels[0].serial_phy = true;
|
||||
channels[0].gateway_id = static_cast<uint8_t>(CONFIG_GATEWAY_CHANNEL1_GW_ID);
|
||||
channels[0].uart_port = 1;
|
||||
#elif CONFIG_GATEWAY_CHANNEL1_PHY_UART2
|
||||
channels[0].enabled = true;
|
||||
channels[0].serial_phy = true;
|
||||
channels[0].gateway_id = static_cast<uint8_t>(CONFIG_GATEWAY_CHANNEL1_GW_ID);
|
||||
channels[0].uart_port = 2;
|
||||
#endif
|
||||
|
||||
#if CONFIG_GATEWAY_CHANNEL_COUNT >= 2
|
||||
#if CONFIG_GATEWAY_CHANNEL2_PHY_NATIVE
|
||||
channels[1].enabled = true;
|
||||
channels[1].native_phy = true;
|
||||
channels[1].gateway_id = static_cast<uint8_t>(CONFIG_GATEWAY_CHANNEL2_GW_ID);
|
||||
channels[1].native_bus_id = static_cast<uint8_t>(CONFIG_GATEWAY_CHANNEL2_NATIVE_BUS_ID);
|
||||
channels[1].native_baudrate = static_cast<uint32_t>(CONFIG_GATEWAY_CHANNEL2_NATIVE_BAUDRATE);
|
||||
#elif CONFIG_GATEWAY_CHANNEL2_PHY_UART1
|
||||
channels[1].enabled = true;
|
||||
channels[1].serial_phy = true;
|
||||
channels[1].gateway_id = static_cast<uint8_t>(CONFIG_GATEWAY_CHANNEL2_GW_ID);
|
||||
channels[1].uart_port = 1;
|
||||
#elif CONFIG_GATEWAY_CHANNEL2_PHY_UART2
|
||||
channels[1].enabled = true;
|
||||
channels[1].serial_phy = true;
|
||||
channels[1].gateway_id = static_cast<uint8_t>(CONFIG_GATEWAY_CHANNEL2_GW_ID);
|
||||
channels[1].uart_port = 2;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
bool any_enabled = false;
|
||||
bool saw_native = false;
|
||||
uint32_t native_baudrate = 0;
|
||||
|
||||
for (int i = 0; i < CONFIG_GATEWAY_CHANNEL_COUNT; ++i) {
|
||||
if (!channels[i].enabled) {
|
||||
continue;
|
||||
}
|
||||
any_enabled = true;
|
||||
for (int j = i + 1; j < CONFIG_GATEWAY_CHANNEL_COUNT; ++j) {
|
||||
if (!channels[j].enabled) {
|
||||
continue;
|
||||
}
|
||||
if (channels[i].gateway_id == channels[j].gateway_id) {
|
||||
ESP_LOGE(kTag, "duplicate gateway ids configured: %u", channels[i].gateway_id);
|
||||
return false;
|
||||
}
|
||||
if (channels[i].serial_phy && channels[j].serial_phy &&
|
||||
channels[i].uart_port == channels[j].uart_port) {
|
||||
ESP_LOGE(kTag, "duplicate serial PHY UART%d configured for multiple channels",
|
||||
channels[i].uart_port);
|
||||
return false;
|
||||
}
|
||||
if (channels[i].native_phy && channels[j].native_phy &&
|
||||
channels[i].native_bus_id == channels[j].native_bus_id) {
|
||||
ESP_LOGE(kTag, "duplicate native DALI bus ids configured: %u",
|
||||
channels[i].native_bus_id);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (channels[i].native_phy) {
|
||||
if (!saw_native) {
|
||||
saw_native = true;
|
||||
native_baudrate = channels[i].native_baudrate;
|
||||
} else if (native_baudrate != channels[i].native_baudrate) {
|
||||
ESP_LOGE(kTag,
|
||||
"mixed native PHY baudrates are not supported by the shared DALI HAL: %lu vs %lu",
|
||||
static_cast<unsigned long>(native_baudrate),
|
||||
static_cast<unsigned long>(channels[i].native_baudrate));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!any_enabled) {
|
||||
ESP_LOGE(kTag, "no DALI PHY is configured; enable at least one native or serial channel");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
esp_err_t BindConfiguredChannels(gateway::DaliDomainService& dali_domain,
|
||||
const gateway::GatewayRuntime& runtime) {
|
||||
#if CONFIG_GATEWAY_CHANNEL1_PHY_NATIVE
|
||||
gateway::DaliHardwareBusConfig channel1{};
|
||||
channel1.channel_index = 0;
|
||||
@@ -39,7 +147,11 @@ void BindConfiguredChannels(gateway::DaliDomainService& dali_domain,
|
||||
channel1.rx_pin = static_cast<uint8_t>(CONFIG_GATEWAY_CHANNEL1_NATIVE_RX_PIN);
|
||||
channel1.baudrate = static_cast<uint32_t>(CONFIG_GATEWAY_CHANNEL1_NATIVE_BAUDRATE);
|
||||
channel1.name = runtime.gatewayName(channel1.gateway_id);
|
||||
LogBindError("channel1 native DALI", dali_domain.bindHardwareBus(channel1));
|
||||
esp_err_t err = dali_domain.bindHardwareBus(channel1);
|
||||
LogBindError("channel1 native DALI", err);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
#elif CONFIG_GATEWAY_CHANNEL1_PHY_UART1 || CONFIG_GATEWAY_CHANNEL1_PHY_UART2
|
||||
gateway::DaliSerialBusConfig channel1{};
|
||||
channel1.channel_index = 0;
|
||||
@@ -53,9 +165,15 @@ void BindConfiguredChannels(gateway::DaliDomainService& dali_domain,
|
||||
channel1.rx_pin = CONFIG_GATEWAY_CHANNEL1_SERIAL_RX_PIN;
|
||||
channel1.baudrate = static_cast<uint32_t>(CONFIG_GATEWAY_CHANNEL1_SERIAL_BAUDRATE);
|
||||
channel1.rx_buffer_size = static_cast<size_t>(CONFIG_GATEWAY_CHANNEL1_SERIAL_RX_BUFFER);
|
||||
channel1.tx_buffer_size = static_cast<size_t>(CONFIG_GATEWAY_CHANNEL1_SERIAL_RX_BUFFER);
|
||||
channel1.tx_buffer_size = static_cast<size_t>(CONFIG_GATEWAY_CHANNEL1_SERIAL_TX_BUFFER);
|
||||
channel1.query_timeout_ms =
|
||||
static_cast<uint32_t>(CONFIG_GATEWAY_CHANNEL1_SERIAL_QUERY_TIMEOUT_MS);
|
||||
channel1.name = runtime.gatewayName(channel1.gateway_id);
|
||||
LogBindError("channel1 serial DALI", dali_domain.bindSerialBus(channel1));
|
||||
esp_err_t err = dali_domain.bindSerialBus(channel1);
|
||||
LogBindError("channel1 serial DALI", err);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CONFIG_GATEWAY_CHANNEL_COUNT >= 2
|
||||
@@ -68,7 +186,11 @@ void BindConfiguredChannels(gateway::DaliDomainService& dali_domain,
|
||||
channel2.rx_pin = static_cast<uint8_t>(CONFIG_GATEWAY_CHANNEL2_NATIVE_RX_PIN);
|
||||
channel2.baudrate = static_cast<uint32_t>(CONFIG_GATEWAY_CHANNEL2_NATIVE_BAUDRATE);
|
||||
channel2.name = runtime.gatewayName(channel2.gateway_id);
|
||||
LogBindError("channel2 native DALI", dali_domain.bindHardwareBus(channel2));
|
||||
esp_err_t err = dali_domain.bindHardwareBus(channel2);
|
||||
LogBindError("channel2 native DALI", err);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
#elif CONFIG_GATEWAY_CHANNEL2_PHY_UART1 || CONFIG_GATEWAY_CHANNEL2_PHY_UART2
|
||||
gateway::DaliSerialBusConfig channel2{};
|
||||
channel2.channel_index = 1;
|
||||
@@ -82,11 +204,19 @@ void BindConfiguredChannels(gateway::DaliDomainService& dali_domain,
|
||||
channel2.rx_pin = CONFIG_GATEWAY_CHANNEL2_SERIAL_RX_PIN;
|
||||
channel2.baudrate = static_cast<uint32_t>(CONFIG_GATEWAY_CHANNEL2_SERIAL_BAUDRATE);
|
||||
channel2.rx_buffer_size = static_cast<size_t>(CONFIG_GATEWAY_CHANNEL2_SERIAL_RX_BUFFER);
|
||||
channel2.tx_buffer_size = static_cast<size_t>(CONFIG_GATEWAY_CHANNEL2_SERIAL_RX_BUFFER);
|
||||
channel2.tx_buffer_size = static_cast<size_t>(CONFIG_GATEWAY_CHANNEL2_SERIAL_TX_BUFFER);
|
||||
channel2.query_timeout_ms =
|
||||
static_cast<uint32_t>(CONFIG_GATEWAY_CHANNEL2_SERIAL_QUERY_TIMEOUT_MS);
|
||||
channel2.name = runtime.gatewayName(channel2.gateway_id);
|
||||
LogBindError("channel2 serial DALI", dali_domain.bindSerialBus(channel2));
|
||||
esp_err_t err = dali_domain.bindSerialBus(channel2);
|
||||
LogBindError("channel2 serial DALI", err);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
@@ -107,6 +237,8 @@ extern "C" void app_main(void) {
|
||||
gateway::GatewayCore core(profile);
|
||||
core.start();
|
||||
|
||||
ESP_ERROR_CHECK(ValidateChannelBindings() ? ESP_OK : ESP_ERR_INVALID_STATE);
|
||||
|
||||
s_dali_domain = std::make_unique<gateway::DaliDomainService>();
|
||||
s_runtime = std::make_unique<gateway::GatewayRuntime>(
|
||||
profile,
|
||||
@@ -118,7 +250,7 @@ extern "C" void app_main(void) {
|
||||
s_dali_domain.get());
|
||||
ESP_ERROR_CHECK(s_runtime->start());
|
||||
s_runtime->setGatewayCount(CONFIG_GATEWAY_CHANNEL_COUNT);
|
||||
BindConfiguredChannels(*s_dali_domain, *s_runtime);
|
||||
ESP_ERROR_CHECK(BindConfiguredChannels(*s_dali_domain, *s_runtime));
|
||||
|
||||
gateway::GatewayControllerConfig controller_config;
|
||||
controller_config.setup_supported = true;
|
||||
@@ -132,6 +264,15 @@ extern "C" void app_main(void) {
|
||||
controller_config);
|
||||
ESP_ERROR_CHECK(s_controller->start());
|
||||
|
||||
if (profile.enable_wifi || profile.enable_eth) {
|
||||
gateway::GatewayNetworkServiceConfig network_config;
|
||||
network_config.http_enabled = true;
|
||||
network_config.udp_enabled = true;
|
||||
s_network = std::make_unique<gateway::GatewayNetworkService>(*s_controller, *s_runtime,
|
||||
network_config);
|
||||
ESP_ERROR_CHECK(s_network->start());
|
||||
}
|
||||
|
||||
if (profile.enable_ble) {
|
||||
s_ble_bridge = std::make_unique<gateway::GatewayBleBridge>(*s_controller, *s_runtime,
|
||||
*s_dali_domain);
|
||||
|
||||
Reference in New Issue
Block a user