From b5f02d0a47c9b1eec10ced2a36dd4bb6f10fbc91 Mon Sep 17 00:00:00 2001 From: Hendrik Groove Date: Tue, 9 Sep 2025 10:53:37 +0200 Subject: [PATCH] truma_inetbox(stream): enqueue keepalive/test; add SO_SNDTIMEO on UDP socket --- components/truma_inetbox/LinBusListener.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/components/truma_inetbox/LinBusListener.cpp b/components/truma_inetbox/LinBusListener.cpp index 8bf698d..ff7795c 100644 --- a/components/truma_inetbox/LinBusListener.cpp +++ b/components/truma_inetbox/LinBusListener.cpp @@ -5,6 +5,7 @@ #ifdef USE_ESP32 #include #include +#include #endif namespace esphome { @@ -438,12 +439,11 @@ void LinBusListener::process_log_queue(TickType_t xTicksToWait) { void LinBusListener::stream_send_test(const std::string &line) { if (!this->stream_enabled_) return; if (this->udp_sock_ < 0) this->stream_try_init_(); - if (this->udp_sock_ < 0) return; + // Always enqueue to avoid blocking the main loop std::string msg = line; if (msg.empty()) msg = "STREAM TEST"; msg.push_back('\n'); - ::sendto(this->udp_sock_, msg.c_str(), msg.size(), 0, (struct sockaddr *) &this->udp_addr_, sizeof(this->udp_addr_)); - this->last_stream_send_ms_ = millis(); + this->stream_enqueue_line_(msg); } void LinBusListener::stream_try_init_() { if (!this->stream_enabled_) return; @@ -457,6 +457,11 @@ void LinBusListener::stream_try_init_() { ESP_LOGW(TAG, "UDP socket create failed"); return; } + // Set a small send timeout so UDP sendto doesn't block long on ARP + struct timeval tv; + tv.tv_sec = 0; + tv.tv_usec = 50000; // 50ms + setsockopt(this->udp_sock_, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)); memset(&this->udp_addr_, 0, sizeof(this->udp_addr_)); this->udp_addr_.sin_family = AF_INET; this->udp_addr_.sin_port = htons(this->udp_port_); @@ -484,12 +489,12 @@ static std::string hex_bytes_(const uint8_t *data, uint8_t len) { } void LinBusListener::stream_maybe_keepalive_() { - if (!this->stream_enabled_ || this->udp_sock_ < 0) return; + if (!this->stream_enabled_) return; const uint32_t now = millis(); if (this->stream_keepalive_ms_ == 0) return; if (now - this->last_stream_send_ms_ >= this->stream_keepalive_ms_) { - const char *msg = "KEEPALIVE"; - ::sendto(this->udp_sock_, msg, strlen(msg), 0, (struct sockaddr *) &this->udp_addr_, sizeof(this->udp_addr_)); + // Enqueue keepalive to be sent from the background sender task + this->stream_enqueue_line_(std::string("KEEPALIVE\n")); this->last_stream_send_ms_ = now; } }