truma_inetbox(stream): enqueue keepalive/test; add SO_SNDTIMEO on UDP socket

This commit is contained in:
Hendrik Groove 2025-09-09 10:53:37 +02:00
parent d0632b8457
commit b5f02d0a47

View File

@ -5,6 +5,7 @@
#ifdef USE_ESP32 #ifdef USE_ESP32
#include <lwip/sockets.h> #include <lwip/sockets.h>
#include <lwip/inet.h> #include <lwip/inet.h>
#include <sys/time.h>
#endif #endif
namespace esphome { namespace esphome {
@ -438,12 +439,11 @@ void LinBusListener::process_log_queue(TickType_t xTicksToWait) {
void LinBusListener::stream_send_test(const std::string &line) { void LinBusListener::stream_send_test(const std::string &line) {
if (!this->stream_enabled_) return; if (!this->stream_enabled_) return;
if (this->udp_sock_ < 0) this->stream_try_init_(); 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; std::string msg = line;
if (msg.empty()) msg = "STREAM TEST"; if (msg.empty()) msg = "STREAM TEST";
msg.push_back('\n'); msg.push_back('\n');
::sendto(this->udp_sock_, msg.c_str(), msg.size(), 0, (struct sockaddr *) &this->udp_addr_, sizeof(this->udp_addr_)); this->stream_enqueue_line_(msg);
this->last_stream_send_ms_ = millis();
} }
void LinBusListener::stream_try_init_() { void LinBusListener::stream_try_init_() {
if (!this->stream_enabled_) return; if (!this->stream_enabled_) return;
@ -457,6 +457,11 @@ void LinBusListener::stream_try_init_() {
ESP_LOGW(TAG, "UDP socket create failed"); ESP_LOGW(TAG, "UDP socket create failed");
return; 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_)); memset(&this->udp_addr_, 0, sizeof(this->udp_addr_));
this->udp_addr_.sin_family = AF_INET; this->udp_addr_.sin_family = AF_INET;
this->udp_addr_.sin_port = htons(this->udp_port_); 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_() { void LinBusListener::stream_maybe_keepalive_() {
if (!this->stream_enabled_ || this->udp_sock_ < 0) return; if (!this->stream_enabled_) return;
const uint32_t now = millis(); const uint32_t now = millis();
if (this->stream_keepalive_ms_ == 0) return; if (this->stream_keepalive_ms_ == 0) return;
if (now - this->last_stream_send_ms_ >= this->stream_keepalive_ms_) { if (now - this->last_stream_send_ms_ >= this->stream_keepalive_ms_) {
const char *msg = "KEEPALIVE"; // Enqueue keepalive to be sent from the background sender task
::sendto(this->udp_sock_, msg, strlen(msg), 0, (struct sockaddr *) &this->udp_addr_, sizeof(this->udp_addr_)); this->stream_enqueue_line_(std::string("KEEPALIVE\n"));
this->last_stream_send_ms_ = now; this->last_stream_send_ms_ = now;
} }
} }