feat: Enhance EtsDeviceRuntime constructor and multicast handling

- Updated EtsDeviceRuntime constructor to accept an optional tunnel_client_address parameter with a default value of 0.
- Modified EspIdfPlatform::setupMultiCast to use IPPROTO_UDP for socket creation and improved multicast interface selection based on the current IP address.
- Ensured that the multicast interface is set only if a valid local address is available.
- Adjusted the client address assignment in EtsDeviceRuntime to use the provided tunnel_client_address if valid, falling back to the default otherwise.

Signed-off-by: Tony <tonylu@tony-cloud.com>
This commit is contained in:
Tony
2026-05-13 12:47:37 +08:00
parent b74367e5a0
commit 39ef630608
11 changed files with 595 additions and 118 deletions
+29 -3
View File
@@ -63,7 +63,8 @@ struct GatewayKnxConfig {
uint8_t main_group{0};
uint16_t udp_port{kGatewayKnxDefaultUdpPort};
std::string multicast_address{kGatewayKnxDefaultMulticastAddress};
uint16_t individual_address{0x1101};
uint16_t ip_interface_individual_address{0xff01};
uint16_t individual_address{0xfffe};
int programming_button_gpio{-1};
bool programming_button_active_low{true};
int programming_led_gpio{-1};
@@ -208,6 +209,9 @@ class GatewayKnxTpIpRouter {
void setGroupWriteHandler(GroupWriteHandler handler);
const GatewayKnxConfig& config() const;
bool tpUartOnline() const;
bool programmingMode();
esp_err_t setProgrammingMode(bool enabled);
esp_err_t toggleProgrammingMode();
esp_err_t start(uint32_t task_stack_size, UBaseType_t task_priority);
esp_err_t stop();
@@ -217,6 +221,14 @@ class GatewayKnxTpIpRouter {
private:
static constexpr size_t kMaxTunnelClients = 16;
static constexpr size_t kMaxTcpClients = 4;
struct TcpClient {
int sock{-1};
::sockaddr_in remote{};
std::vector<uint8_t> rx_buffer;
TickType_t last_activity_tick{0};
};
struct TunnelClient {
bool connected{false};
@@ -225,6 +237,7 @@ class GatewayKnxTpIpRouter {
uint8_t received_sequence{255};
uint8_t send_sequence{0};
uint16_t individual_address{0};
int tcp_sock{-1};
TickType_t last_activity_tick{0};
::sockaddr_in control_remote{};
::sockaddr_in data_remote{};
@@ -237,6 +250,9 @@ class GatewayKnxTpIpRouter {
void finishTask();
void closeSockets();
bool configureSocket();
void handleTcpAccept();
void handleTcpClient(TcpClient& client);
void closeTcpClient(TcpClient& client);
bool configureTpUart();
bool initializeTpUart();
bool configureProgrammingGpio();
@@ -276,7 +292,12 @@ class GatewayKnxTpIpRouter {
void sendSearchResponse(uint16_t service, const ::sockaddr_in& remote,
const std::set<uint8_t>& requested_dibs = {});
void sendDescriptionResponse(const ::sockaddr_in& remote);
std::array<uint8_t, 8> localHpaiForRemote(const ::sockaddr_in& remote) const;
bool sendPacket(const std::vector<uint8_t>& packet, const ::sockaddr_in& remote) const;
bool sendPacketToTunnelClient(const TunnelClient& client,
const std::vector<uint8_t>& packet) const;
bool currentTransportAllowsTcpHpai() const;
std::optional<std::array<uint8_t, 8>> localHpaiForRemote(const ::sockaddr_in& remote,
bool tcp = false) const;
std::vector<uint8_t> buildDeviceInfoDib(const ::sockaddr_in& remote) const;
std::vector<uint8_t> buildSupportedServiceDib() const;
std::vector<uint8_t> buildExtendedDeviceInfoDib() const;
@@ -298,8 +319,10 @@ class GatewayKnxTpIpRouter {
void selectOpenKnxNetworkInterface(const ::sockaddr_in& remote);
bool emitOpenKnxGroupValue(uint16_t group_object_number, const uint8_t* data, size_t len);
bool shouldRouteDaliApplicationFrames() const;
uint8_t advertisedMedium() const;
void syncOpenKnxConfigFromDevice();
uint16_t effectiveIndividualAddress() const;
uint16_t effectiveIpInterfaceIndividualAddress() const;
uint16_t effectiveKnxDeviceIndividualAddress() const;
uint16_t effectiveTunnelAddress() const;
void pollTpUart();
void pollProgrammingButton();
@@ -322,9 +345,12 @@ class GatewayKnxTpIpRouter {
std::atomic_bool stop_requested_{false};
std::atomic_bool started_{false};
int udp_sock_{-1};
int tcp_sock_{-1};
int active_tcp_sock_{-1};
int tp_uart_port_{-1};
std::vector<uint32_t> multicast_joined_interfaces_;
TickType_t network_refresh_tick_{0};
std::array<TcpClient, kMaxTcpClients> tcp_clients_{};
std::array<TunnelClient, kMaxTunnelClients> tunnel_clients_{};
uint8_t last_tunnel_channel_id_{0};
std::vector<uint8_t> tp_rx_frame_;