Refactor channel binding configuration and validation

- Introduced `NativeChannelConfig` and `SerialChannelConfig` functions to streamline the creation of `ChannelBindingConfig` instances.
- Replaced manual channel configuration with macros `GATEWAY_CONFIGURE_NATIVE_CHANNEL` and `GATEWAY_CONFIGURE_SERIAL_CHANNEL` for better maintainability.
- Updated `BuildChannelBindings` to utilize the new configuration functions, reducing redundancy.
- Enhanced `ValidateChannelBindings` to check for required TX and RX GPIO pins for native channels.
- Simplified `BindConfiguredChannels` to iterate over the built channel bindings, improving readability and reducing code duplication.
- Adjusted the handling of reserved UART ports in `app_main` to dynamically include all serial channels.
- Updated SDK configuration for channel 1 gateway ID and modified KNX-related configurations for enhanced functionality.
- Removed obsolete NVS flash initialization code and replaced it with a more streamlined approach for managing runtime data.
- Added a new command in `GatewayController` to publish gateway IDs when requested.
- Defined a constant for maximum KNX instance count to improve clarity in the codebase.

Signed-off-by: Tony <tonylu@tony-cloud.com>
This commit is contained in:
Tony
2026-05-27 18:08:53 +08:00
parent 7a820e700c
commit 6d0b36b60a
8 changed files with 1579 additions and 161 deletions
File diff suppressed because it is too large Load Diff
+274 -127
View File
@@ -12,6 +12,7 @@
#include "esp_log.h"
#include "sdkconfig.h"
#include <array>
#include <cstdio>
#include <cstdint>
#include <memory>
@@ -525,57 +526,245 @@ struct ChannelBindingConfig {
bool enabled{false};
bool native_phy{false};
bool serial_phy{false};
uint8_t channel_index{0};
uint8_t gateway_id{0};
uint8_t native_bus_id{0};
uint32_t native_baudrate{0};
int native_tx_pin{-1};
int native_rx_pin{-1};
int uart_port{-1};
int serial_tx_pin{-1};
int serial_rx_pin{-1};
uint32_t serial_baudrate{0};
size_t serial_rx_buffer_size{0};
size_t serial_tx_buffer_size{0};
uint32_t serial_query_timeout_ms{0};
};
ChannelBindingConfig NativeChannelConfig(uint8_t channel_index, uint8_t gateway_id,
uint8_t bus_id, int tx_pin, int rx_pin,
uint32_t baudrate) {
ChannelBindingConfig channel{};
channel.enabled = true;
channel.native_phy = true;
channel.channel_index = channel_index;
channel.gateway_id = gateway_id;
channel.native_bus_id = bus_id;
channel.native_tx_pin = tx_pin;
channel.native_rx_pin = rx_pin;
channel.native_baudrate = baudrate;
return channel;
}
[[maybe_unused]] ChannelBindingConfig SerialChannelConfig(uint8_t channel_index, uint8_t gateway_id,
int uart_port, int tx_pin, int rx_pin,
uint32_t baudrate, size_t rx_buffer_size,
size_t tx_buffer_size,
uint32_t query_timeout_ms) {
ChannelBindingConfig channel{};
channel.enabled = true;
channel.serial_phy = true;
channel.channel_index = channel_index;
channel.gateway_id = gateway_id;
channel.uart_port = uart_port;
channel.serial_tx_pin = tx_pin;
channel.serial_rx_pin = rx_pin;
channel.serial_baudrate = baudrate;
channel.serial_rx_buffer_size = rx_buffer_size;
channel.serial_tx_buffer_size = tx_buffer_size;
channel.serial_query_timeout_ms = query_timeout_ms;
return channel;
}
#define GATEWAY_CONFIGURE_NATIVE_CHANNEL(slot, number) \
channels[slot] = NativeChannelConfig( \
static_cast<uint8_t>(slot), static_cast<uint8_t>(CONFIG_GATEWAY_CHANNEL##number##_GW_ID), \
static_cast<uint8_t>(CONFIG_GATEWAY_CHANNEL##number##_NATIVE_BUS_ID), \
CONFIG_GATEWAY_CHANNEL##number##_NATIVE_TX_PIN, \
CONFIG_GATEWAY_CHANNEL##number##_NATIVE_RX_PIN, \
static_cast<uint32_t>(CONFIG_GATEWAY_CHANNEL##number##_NATIVE_BAUDRATE))
#define GATEWAY_CONFIGURE_SERIAL_CHANNEL(slot, number, uart) \
channels[slot] = SerialChannelConfig( \
static_cast<uint8_t>(slot), static_cast<uint8_t>(CONFIG_GATEWAY_CHANNEL##number##_GW_ID), \
uart, CONFIG_GATEWAY_CHANNEL##number##_SERIAL_TX_PIN, \
CONFIG_GATEWAY_CHANNEL##number##_SERIAL_RX_PIN, \
static_cast<uint32_t>(CONFIG_GATEWAY_CHANNEL##number##_SERIAL_BAUDRATE), \
static_cast<size_t>(CONFIG_GATEWAY_CHANNEL##number##_SERIAL_RX_BUFFER), \
static_cast<size_t>(CONFIG_GATEWAY_CHANNEL##number##_SERIAL_TX_BUFFER), \
static_cast<uint32_t>(CONFIG_GATEWAY_CHANNEL##number##_SERIAL_QUERY_TIMEOUT_MS))
std::array<ChannelBindingConfig, CONFIG_GATEWAY_CHANNEL_COUNT> BuildChannelBindings() {
std::array<ChannelBindingConfig, CONFIG_GATEWAY_CHANNEL_COUNT> channels{};
#if CONFIG_GATEWAY_CHANNEL1_PHY_NATIVE
GATEWAY_CONFIGURE_NATIVE_CHANNEL(0, 1);
#elif CONFIG_GATEWAY_CHANNEL1_PHY_UART1
GATEWAY_CONFIGURE_SERIAL_CHANNEL(0, 1, 1);
#elif CONFIG_GATEWAY_CHANNEL1_PHY_UART2
GATEWAY_CONFIGURE_SERIAL_CHANNEL(0, 1, 2);
#endif
#if CONFIG_GATEWAY_CHANNEL_COUNT >= 2
#if CONFIG_GATEWAY_CHANNEL2_PHY_NATIVE
GATEWAY_CONFIGURE_NATIVE_CHANNEL(1, 2);
#elif CONFIG_GATEWAY_CHANNEL2_PHY_UART1
GATEWAY_CONFIGURE_SERIAL_CHANNEL(1, 2, 1);
#elif CONFIG_GATEWAY_CHANNEL2_PHY_UART2
GATEWAY_CONFIGURE_SERIAL_CHANNEL(1, 2, 2);
#endif
#endif
#if CONFIG_GATEWAY_CHANNEL_COUNT >= 3
#if CONFIG_GATEWAY_CHANNEL3_PHY_NATIVE
GATEWAY_CONFIGURE_NATIVE_CHANNEL(2, 3);
#elif CONFIG_GATEWAY_CHANNEL3_PHY_UART1
GATEWAY_CONFIGURE_SERIAL_CHANNEL(2, 3, 1);
#elif CONFIG_GATEWAY_CHANNEL3_PHY_UART2
GATEWAY_CONFIGURE_SERIAL_CHANNEL(2, 3, 2);
#endif
#endif
#if CONFIG_GATEWAY_CHANNEL_COUNT >= 4
#if CONFIG_GATEWAY_CHANNEL4_PHY_NATIVE
GATEWAY_CONFIGURE_NATIVE_CHANNEL(3, 4);
#elif CONFIG_GATEWAY_CHANNEL4_PHY_UART1
GATEWAY_CONFIGURE_SERIAL_CHANNEL(3, 4, 1);
#elif CONFIG_GATEWAY_CHANNEL4_PHY_UART2
GATEWAY_CONFIGURE_SERIAL_CHANNEL(3, 4, 2);
#endif
#endif
#if CONFIG_GATEWAY_CHANNEL_COUNT >= 5
#if CONFIG_GATEWAY_CHANNEL5_PHY_NATIVE
GATEWAY_CONFIGURE_NATIVE_CHANNEL(4, 5);
#elif CONFIG_GATEWAY_CHANNEL5_PHY_UART1
GATEWAY_CONFIGURE_SERIAL_CHANNEL(4, 5, 1);
#elif CONFIG_GATEWAY_CHANNEL5_PHY_UART2
GATEWAY_CONFIGURE_SERIAL_CHANNEL(4, 5, 2);
#endif
#endif
#if CONFIG_GATEWAY_CHANNEL_COUNT >= 6
#if CONFIG_GATEWAY_CHANNEL6_PHY_NATIVE
GATEWAY_CONFIGURE_NATIVE_CHANNEL(5, 6);
#elif CONFIG_GATEWAY_CHANNEL6_PHY_UART1
GATEWAY_CONFIGURE_SERIAL_CHANNEL(5, 6, 1);
#elif CONFIG_GATEWAY_CHANNEL6_PHY_UART2
GATEWAY_CONFIGURE_SERIAL_CHANNEL(5, 6, 2);
#endif
#endif
#if CONFIG_GATEWAY_CHANNEL_COUNT >= 7
#if CONFIG_GATEWAY_CHANNEL7_PHY_NATIVE
GATEWAY_CONFIGURE_NATIVE_CHANNEL(6, 7);
#elif CONFIG_GATEWAY_CHANNEL7_PHY_UART1
GATEWAY_CONFIGURE_SERIAL_CHANNEL(6, 7, 1);
#elif CONFIG_GATEWAY_CHANNEL7_PHY_UART2
GATEWAY_CONFIGURE_SERIAL_CHANNEL(6, 7, 2);
#endif
#endif
#if CONFIG_GATEWAY_CHANNEL_COUNT >= 8
#if CONFIG_GATEWAY_CHANNEL8_PHY_NATIVE
GATEWAY_CONFIGURE_NATIVE_CHANNEL(7, 8);
#elif CONFIG_GATEWAY_CHANNEL8_PHY_UART1
GATEWAY_CONFIGURE_SERIAL_CHANNEL(7, 8, 1);
#elif CONFIG_GATEWAY_CHANNEL8_PHY_UART2
GATEWAY_CONFIGURE_SERIAL_CHANNEL(7, 8, 2);
#endif
#endif
#if CONFIG_GATEWAY_CHANNEL_COUNT >= 9
#if CONFIG_GATEWAY_CHANNEL9_PHY_NATIVE
GATEWAY_CONFIGURE_NATIVE_CHANNEL(8, 9);
#elif CONFIG_GATEWAY_CHANNEL9_PHY_UART1
GATEWAY_CONFIGURE_SERIAL_CHANNEL(8, 9, 1);
#elif CONFIG_GATEWAY_CHANNEL9_PHY_UART2
GATEWAY_CONFIGURE_SERIAL_CHANNEL(8, 9, 2);
#endif
#endif
#if CONFIG_GATEWAY_CHANNEL_COUNT >= 10
#if CONFIG_GATEWAY_CHANNEL10_PHY_NATIVE
GATEWAY_CONFIGURE_NATIVE_CHANNEL(9, 10);
#elif CONFIG_GATEWAY_CHANNEL10_PHY_UART1
GATEWAY_CONFIGURE_SERIAL_CHANNEL(9, 10, 1);
#elif CONFIG_GATEWAY_CHANNEL10_PHY_UART2
GATEWAY_CONFIGURE_SERIAL_CHANNEL(9, 10, 2);
#endif
#endif
#if CONFIG_GATEWAY_CHANNEL_COUNT >= 11
#if CONFIG_GATEWAY_CHANNEL11_PHY_NATIVE
GATEWAY_CONFIGURE_NATIVE_CHANNEL(10, 11);
#elif CONFIG_GATEWAY_CHANNEL11_PHY_UART1
GATEWAY_CONFIGURE_SERIAL_CHANNEL(10, 11, 1);
#elif CONFIG_GATEWAY_CHANNEL11_PHY_UART2
GATEWAY_CONFIGURE_SERIAL_CHANNEL(10, 11, 2);
#endif
#endif
#if CONFIG_GATEWAY_CHANNEL_COUNT >= 12
#if CONFIG_GATEWAY_CHANNEL12_PHY_NATIVE
GATEWAY_CONFIGURE_NATIVE_CHANNEL(11, 12);
#elif CONFIG_GATEWAY_CHANNEL12_PHY_UART1
GATEWAY_CONFIGURE_SERIAL_CHANNEL(11, 12, 1);
#elif CONFIG_GATEWAY_CHANNEL12_PHY_UART2
GATEWAY_CONFIGURE_SERIAL_CHANNEL(11, 12, 2);
#endif
#endif
#if CONFIG_GATEWAY_CHANNEL_COUNT >= 13
#if CONFIG_GATEWAY_CHANNEL13_PHY_NATIVE
GATEWAY_CONFIGURE_NATIVE_CHANNEL(12, 13);
#elif CONFIG_GATEWAY_CHANNEL13_PHY_UART1
GATEWAY_CONFIGURE_SERIAL_CHANNEL(12, 13, 1);
#elif CONFIG_GATEWAY_CHANNEL13_PHY_UART2
GATEWAY_CONFIGURE_SERIAL_CHANNEL(12, 13, 2);
#endif
#endif
#if CONFIG_GATEWAY_CHANNEL_COUNT >= 14
#if CONFIG_GATEWAY_CHANNEL14_PHY_NATIVE
GATEWAY_CONFIGURE_NATIVE_CHANNEL(13, 14);
#elif CONFIG_GATEWAY_CHANNEL14_PHY_UART1
GATEWAY_CONFIGURE_SERIAL_CHANNEL(13, 14, 1);
#elif CONFIG_GATEWAY_CHANNEL14_PHY_UART2
GATEWAY_CONFIGURE_SERIAL_CHANNEL(13, 14, 2);
#endif
#endif
#if CONFIG_GATEWAY_CHANNEL_COUNT >= 15
#if CONFIG_GATEWAY_CHANNEL15_PHY_NATIVE
GATEWAY_CONFIGURE_NATIVE_CHANNEL(14, 15);
#elif CONFIG_GATEWAY_CHANNEL15_PHY_UART1
GATEWAY_CONFIGURE_SERIAL_CHANNEL(14, 15, 1);
#elif CONFIG_GATEWAY_CHANNEL15_PHY_UART2
GATEWAY_CONFIGURE_SERIAL_CHANNEL(14, 15, 2);
#endif
#endif
#if CONFIG_GATEWAY_CHANNEL_COUNT >= 16
#if CONFIG_GATEWAY_CHANNEL16_PHY_NATIVE
GATEWAY_CONFIGURE_NATIVE_CHANNEL(15, 16);
#elif CONFIG_GATEWAY_CHANNEL16_PHY_UART1
GATEWAY_CONFIGURE_SERIAL_CHANNEL(15, 16, 1);
#elif CONFIG_GATEWAY_CHANNEL16_PHY_UART2
GATEWAY_CONFIGURE_SERIAL_CHANNEL(15, 16, 2);
#endif
#endif
return channels;
}
bool ValidateChannelBindings() {
if (k485ControlEnabled && kConsoleOnUart0) {
ESP_LOGE(kTag, "485 control bridge requires moving the ESP-IDF console off UART0");
return false;
}
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
const auto channels = BuildChannelBindings();
bool any_enabled = false;
bool saw_native = false;
@@ -586,6 +775,11 @@ bool ValidateChannelBindings() {
continue;
}
any_enabled = true;
if (channels[i].native_phy &&
(channels[i].native_tx_pin < 0 || channels[i].native_rx_pin < 0)) {
ESP_LOGE(kTag, "native DALI channel %d requires TX and RX GPIO pins", i + 1);
return false;
}
for (int j = i + 1; j < CONFIG_GATEWAY_CHANNEL_COUNT; ++j) {
if (!channels[j].enabled) {
continue;
@@ -695,83 +889,43 @@ bool ValidateChannelBindings() {
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;
channel1.gateway_id = static_cast<uint8_t>(CONFIG_GATEWAY_CHANNEL1_GW_ID);
channel1.bus_id = static_cast<uint8_t>(CONFIG_GATEWAY_CHANNEL1_NATIVE_BUS_ID);
channel1.tx_pin = static_cast<uint8_t>(CONFIG_GATEWAY_CHANNEL1_NATIVE_TX_PIN);
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);
esp_err_t err = dali_domain.bindHardwareBus(channel1);
LogBindError("channel1 native DALI", err);
if (err != ESP_OK) {
return err;
for (const auto& channel : BuildChannelBindings()) {
if (!channel.enabled) {
continue;
}
if (channel.native_phy) {
gateway::DaliHardwareBusConfig config{};
config.channel_index = channel.channel_index;
config.gateway_id = channel.gateway_id;
config.bus_id = channel.native_bus_id;
config.tx_pin = static_cast<uint8_t>(channel.native_tx_pin);
config.rx_pin = static_cast<uint8_t>(channel.native_rx_pin);
config.baudrate = channel.native_baudrate;
config.name = runtime.gatewayName(config.gateway_id);
const esp_err_t err = dali_domain.bindHardwareBus(config);
LogBindError(config.name.c_str(), err);
if (err != ESP_OK) {
return err;
}
} else if (channel.serial_phy) {
gateway::DaliSerialBusConfig config{};
config.channel_index = channel.channel_index;
config.gateway_id = channel.gateway_id;
config.uart_port = channel.uart_port;
config.tx_pin = channel.serial_tx_pin;
config.rx_pin = channel.serial_rx_pin;
config.baudrate = channel.serial_baudrate;
config.rx_buffer_size = channel.serial_rx_buffer_size;
config.tx_buffer_size = channel.serial_tx_buffer_size;
config.query_timeout_ms = channel.serial_query_timeout_ms;
config.name = runtime.gatewayName(config.gateway_id);
const esp_err_t err = dali_domain.bindSerialBus(config);
LogBindError(config.name.c_str(), 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;
channel1.gateway_id = static_cast<uint8_t>(CONFIG_GATEWAY_CHANNEL1_GW_ID);
#if CONFIG_GATEWAY_CHANNEL1_PHY_UART1
channel1.uart_port = 1;
#else
channel1.uart_port = 2;
#endif
channel1.tx_pin = CONFIG_GATEWAY_CHANNEL1_SERIAL_TX_PIN;
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_TX_BUFFER);
channel1.query_timeout_ms =
static_cast<uint32_t>(CONFIG_GATEWAY_CHANNEL1_SERIAL_QUERY_TIMEOUT_MS);
channel1.name = runtime.gatewayName(channel1.gateway_id);
esp_err_t err1 = dali_domain.bindSerialBus(channel1);
LogBindError("channel1 serial DALI", err1);
if (err1 != ESP_OK) {
return err1;
}
#endif
#if CONFIG_GATEWAY_CHANNEL_COUNT >= 2
#if CONFIG_GATEWAY_CHANNEL2_PHY_NATIVE
gateway::DaliHardwareBusConfig channel2{};
channel2.channel_index = 1;
channel2.gateway_id = static_cast<uint8_t>(CONFIG_GATEWAY_CHANNEL2_GW_ID);
channel2.bus_id = static_cast<uint8_t>(CONFIG_GATEWAY_CHANNEL2_NATIVE_BUS_ID);
channel2.tx_pin = static_cast<uint8_t>(CONFIG_GATEWAY_CHANNEL2_NATIVE_TX_PIN);
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);
esp_err_t err2 = dali_domain.bindHardwareBus(channel2);
LogBindError("channel2 native DALI", err2);
if (err2 != ESP_OK) {
return err2;
}
#elif CONFIG_GATEWAY_CHANNEL2_PHY_UART1 || CONFIG_GATEWAY_CHANNEL2_PHY_UART2
gateway::DaliSerialBusConfig channel2{};
channel2.channel_index = 1;
channel2.gateway_id = static_cast<uint8_t>(CONFIG_GATEWAY_CHANNEL2_GW_ID);
#if CONFIG_GATEWAY_CHANNEL2_PHY_UART1
channel2.uart_port = 1;
#else
channel2.uart_port = 2;
#endif
channel2.tx_pin = CONFIG_GATEWAY_CHANNEL2_SERIAL_TX_PIN;
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_TX_BUFFER);
channel2.query_timeout_ms =
static_cast<uint32_t>(CONFIG_GATEWAY_CHANNEL2_SERIAL_QUERY_TIMEOUT_MS);
channel2.name = runtime.gatewayName(channel2.gateway_id);
esp_err_t err2 = dali_domain.bindSerialBus(channel2);
LogBindError("channel2 serial DALI", err2);
if (err2 != ESP_OK) {
return err2;
}
#endif
#endif
return ESP_OK;
}
@@ -880,18 +1034,11 @@ extern "C" void app_main(void) {
static_cast<UBaseType_t>(CONFIG_GATEWAY_BRIDGE_MODBUS_TASK_PRIORITY);
bridge_config.allow_modbus_uart0 = kModbusAllowUart0 && !kConsoleOnUart0 && !k485ControlEnabled;
bridge_config.allow_knx_uart0 = !kConsoleOnUart0 && !k485ControlEnabled;
#if CONFIG_GATEWAY_CHANNEL1_PHY_UART1
bridge_config.reserved_uart_ports.push_back(1);
#elif CONFIG_GATEWAY_CHANNEL1_PHY_UART2
bridge_config.reserved_uart_ports.push_back(2);
#endif
#if CONFIG_GATEWAY_CHANNEL_COUNT >= 2
#if CONFIG_GATEWAY_CHANNEL2_PHY_UART1
bridge_config.reserved_uart_ports.push_back(1);
#elif CONFIG_GATEWAY_CHANNEL2_PHY_UART2
bridge_config.reserved_uart_ports.push_back(2);
#endif
#endif
for (const auto& channel : BuildChannelBindings()) {
if (channel.enabled && channel.serial_phy) {
bridge_config.reserved_uart_ports.push_back(channel.uart_port);
}
}
if (kModbusBridgeSupported) {
gateway::GatewayModbusConfig default_modbus;
#if defined(CONFIG_GATEWAY_MODBUS_DEFAULT_TRANSPORT_RTU)
+1 -1
View File
@@ -605,7 +605,7 @@ CONFIG_GATEWAY_CHANNEL_COUNT=2
#
# Gateway Channel 1
#
CONFIG_GATEWAY_CHANNEL1_GW_ID=3
CONFIG_GATEWAY_CHANNEL1_GW_ID=0
# CONFIG_GATEWAY_CHANNEL1_PHY_DISABLED is not set
CONFIG_GATEWAY_CHANNEL1_PHY_NATIVE=y
# CONFIG_GATEWAY_CHANNEL1_PHY_UART1 is not set
+11 -2
View File
@@ -696,7 +696,7 @@ CONFIG_GATEWAY_KNX_INSTANCE_COUNT=1
CONFIG_GATEWAY_KNX_BRIDGE_SUPPORTED=y
CONFIG_GATEWAY_START_KNX_BRIDGE_ENABLED=y
CONFIG_GATEWAY_KNX_DATA_SECURE_SUPPORTED=y
# CONFIG_GATEWAY_KNX_IP_SECURE_SUPPORTED is not set
CONFIG_GATEWAY_KNX_IP_SECURE_SUPPORTED=y
CONFIG_GATEWAY_KNX_SECURITY_DEV_ENDPOINTS=y
CONFIG_GATEWAY_KNX_SECURITY_PLAIN_NVS=y
CONFIG_GATEWAY_KNX_OEM_MANUFACTURER_ID=0x01e5
@@ -712,7 +712,16 @@ CONFIG_GATEWAY_KNX_UDP_PORT=3671
CONFIG_GATEWAY_KNX_MULTICAST_ADDRESS="224.0.23.12"
CONFIG_GATEWAY_KNX_IP_INTERFACE_INDIVIDUAL_ADDRESS=65281
CONFIG_GATEWAY_KNX_INDIVIDUAL_ADDRESS=65534
# CONFIG_GATEWAY_KNX_OAM_ROUTER_SUPPORTED is not set
CONFIG_GATEWAY_KNX_OAM_ROUTER_SUPPORTED=y
CONFIG_GATEWAY_KNX_OAM_ROUTER_ENABLED=y
CONFIG_GATEWAY_KNX_OAM_ROUTER_OEM_MANUFACTURER_ID=0x00FA
CONFIG_GATEWAY_KNX_OAM_ROUTER_HARDWARE_ID=0x0001
CONFIG_GATEWAY_KNX_OAM_ROUTER_APPLICATION_NUMBER=0xA11F
CONFIG_GATEWAY_KNX_OAM_ROUTER_APPLICATION_VERSION=0x07
CONFIG_GATEWAY_KNX_OAM_ROUTER_INDIVIDUAL_ADDRESS=65282
CONFIG_GATEWAY_KNX_OAM_ROUTER_TUNNEL_ADDRESS_BASE=65296
CONFIG_GATEWAY_KNX_OAM_PROGRAMMING_BUTTON_GPIO=-1
CONFIG_GATEWAY_KNX_OAM_PROGRAMMING_LED_GPIO=-1
CONFIG_GATEWAY_KNX_PROGRAMMING_BUTTON_GPIO=0
CONFIG_GATEWAY_KNX_PROGRAMMING_BUTTON_ACTIVE_LOW=y
CONFIG_GATEWAY_KNX_PROGRAMMING_LED_GPIO=10
@@ -16,6 +16,7 @@
#include "gateway_modbus.hpp"
#include "gateway_provisioning.hpp"
#include "log.hpp"
#include "esp_idf_platform.h"
#include "security_storage.h"
#include "cJSON.h"
@@ -25,7 +26,6 @@
#endif
#include "esp_log.h"
#include "nvs.h"
#include "nvs_flash.h"
#include "sdkconfig.h"
#include "freertos/semphr.h"
#include "lwip/inet.h"
@@ -415,32 +415,11 @@ std::optional<uint32_t> QueryKnxInstanceId(std::string_view query) {
return ValidKnxInstanceId(QueryInt(query, "instanceId", "instance").value_or(0));
}
bool EnsureBridgeNvsReady() {
const esp_err_t err = nvs_flash_init();
if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {
if (nvs_flash_erase() != ESP_OK) {
return false;
}
return nvs_flash_init() == ESP_OK;
}
return err == ESP_OK || err == ESP_ERR_INVALID_STATE;
}
bool EraseOpenKnxEeprom(const std::string& nvs_namespace) {
if (nvs_namespace.empty() || !EnsureBridgeNvsReady()) {
bool EraseOpenKnxRuntimeData(const std::string& nvs_namespace) {
if (nvs_namespace.empty()) {
return false;
}
nvs_handle_t handle = 0;
esp_err_t err = nvs_open(nvs_namespace.c_str(), NVS_READWRITE, &handle);
if (err != ESP_OK) {
return err == ESP_ERR_NVS_NOT_FOUND;
}
err = nvs_erase_key(handle, "eeprom");
if (err == ESP_OK) {
err = nvs_commit(handle);
}
nvs_close(handle);
return err == ESP_OK || err == ESP_ERR_NVS_NOT_FOUND;
return openknx::EraseOpenKnxPropertyStorage(nvs_namespace);
}
std::optional<int> JsonIntAny(const cJSON* parent, const char* primary, const char* fallback) {
@@ -4975,7 +4954,7 @@ GatewayBridgeHttpResponse GatewayBridgeService::handlePost(
if (instance_id.value() != 0) {
nvs_namespace += "_" + std::to_string(instance_id.value());
}
if (!EraseOpenKnxEeprom(nvs_namespace)) {
if (!EraseOpenKnxRuntimeData(nvs_namespace)) {
return ErrorResponse(ESP_FAIL, "failed to erase KNX runtime data");
}
@@ -742,6 +742,14 @@ void GatewayController::dispatchCommand(const std::vector<uint8_t>& command) {
const uint8_t opcode = command[3];
const uint8_t addr = command[4];
const uint8_t data = command[5];
if (opcode == 0x09 && addr == 0x00) {
const auto ids = gatewayIds();
const auto count = std::min<size_t>(ids.size(), 16);
std::vector<uint8_t> payload{0x09, static_cast<uint8_t>(count)};
payload.insert(payload.end(), ids.begin(), ids.begin() + count);
publishPayload(gateway_id, payload);
return;
}
if (!hasGateway(gateway_id)) {
ESP_LOGW(kTag, "command for unknown gateway=%u opcode=0x%02x", gateway_id, opcode);
return;
@@ -72,8 +72,9 @@ inline constexpr uint8_t kReg1DaliProgramVersion[5] = {
static_cast<uint8_t>(kReg1DaliApplicationNumber & 0xff),
kReg1DaliApplicationVersion};
inline constexpr uint32_t kDaliMaxKnxInstanceCount = 16;
inline constexpr uint32_t kReg1DaliSerialMacIncrement = 0;
inline constexpr uint32_t kOamRouterSerialMacIncrement = 1;
inline constexpr uint32_t kOamRouterSerialMacIncrement = kDaliMaxKnxInstanceCount;
inline constexpr uint16_t kOamRouterDeviceDescriptor = 0x091A;
inline constexpr uint16_t kOamRouterManufacturerId =
static_cast<uint16_t>(CONFIG_GATEWAY_KNX_OAM_ROUTER_OEM_MANUFACTURER_ID);
+1 -1
Submodule knx updated: d2bdeb14b6...ae3645239f