From 904358fb1576744bdc88ff25248533321a991b9e Mon Sep 17 00:00:00 2001 From: David Sutton Date: Thu, 29 Oct 2026 15:53:41 +1030 Subject: [PATCH 1/4] ESP/Netsender: Avoid continuous polling when unconfigured Use a 5 second retry period when no monitoring period is available, and reject a configured monPeriod of zero. This prevents an unconfigured or zero-configured device from issuing poll requests every loop iteration. --- .../components/netsender/netsender.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/esp/speaker-netsender/components/netsender/netsender.cpp b/esp/speaker-netsender/components/netsender/netsender.cpp index 8269a63..7f93d3c 100644 --- a/esp/speaker-netsender/components/netsender/netsender.cpp +++ b/esp/speaker-netsender/components/netsender/netsender.cpp @@ -67,6 +67,10 @@ static constexpr const auto MAX_URL_LEN = 256; static constexpr const auto STORAGE_NAMESPACE = "netsender"; static constexpr const auto CONFIG_NVS_KEY = "config"; +// Used when no monitoring period is configured, so an unconfigured device +// does not poll continuously. +static constexpr const auto RETRY_PERIOD = 5; + static constexpr const char *TAG = "netsender"; // Static definition of the netsender task stack. @@ -134,6 +138,11 @@ Netsender::Netsender() this->configured = true; } + // Avoid polling continuously if no monitoring period is stored. + if (this->config.monPeriod <= 0) { + this->config.monPeriod = RETRY_PERIOD; + } + // Initialise HTTP handler. ESP_ERROR_CHECK(init_http_handle()); } @@ -447,7 +456,7 @@ esp_err_t Netsender::req_config() if (netsender_extract_json(resp_buf, "mp", param, sizeof(param)) && parse_int(param, number) && number != this->config.monPeriod) { - if (number >= 0 && number <= SHRT_MAX) { + if (number > 0 && number <= SHRT_MAX) { this->config.monPeriod = static_cast(number); ESP_LOGI(TAG, "monPeriod changed: %d", this->config.monPeriod); changed = true; From 55b84894dcea9dd4c30f6ad62f4021983b29b1a5 Mon Sep 17 00:00:00 2001 From: David Sutton Date: Thu, 29 Oct 2026 15:54:15 +1030 Subject: [PATCH 2/4] ESP/Pipi: Do not abort when a new log file cannot be opened get_logs() previously used ESP_ERROR_CHECK when rotating log files, so an SD card write failure would abort the firmware. Return -1 instead and let the log reader handle the failure gracefully, which is important when the SD card is failing at runtime (#121). --- esp/speaker-netsender/components/pipi/pipi.cpp | 7 ++++++- esp/speaker-netsender/main/log.cpp | 4 ++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/esp/speaker-netsender/components/pipi/pipi.cpp b/esp/speaker-netsender/components/pipi/pipi.cpp index 023a175..a824b31 100644 --- a/esp/speaker-netsender/components/pipi/pipi.cpp +++ b/esp/speaker-netsender/components/pipi/pipi.cpp @@ -40,6 +40,7 @@ #include #include "esp_err.h" +#include "esp_log.h" // Logging Tag. static constexpr auto TAG = "Pipi"; @@ -207,7 +208,11 @@ esp_err_t Pipi::FileLogger::log(char *msg) int Pipi::FileLogger::get_logs() { - ESP_ERROR_CHECK(this->new_file()); + auto err = this->new_file(); + if (err != ESP_OK) { + ESP_LOGE(TAG, "unable to start new log file: %s", esp_err_to_name(err)); + return -1; + } return this->prev_file; } diff --git a/esp/speaker-netsender/main/log.cpp b/esp/speaker-netsender/main/log.cpp index 3269539..b90f56e 100644 --- a/esp/speaker-netsender/main/log.cpp +++ b/esp/speaker-netsender/main/log.cpp @@ -114,6 +114,10 @@ esp_err_t init_log_queue() static std::optional> read_logs() { auto logs_fd = p->get_logs(); + if (logs_fd < 0) { + ESP_LOGE(TAG, "unable to open a log file for reading"); + return std::nullopt; + } if (::lseek(logs_fd, 0, SEEK_SET) == -1) { ESP_LOGE(TAG, "unable to seek logs: %s (%d)", strerror(errno), errno); From 543194cbdce45fda65979af883c10c34ed04a0d6 Mon Sep 17 00:00:00 2001 From: David Sutton Date: Thu, 29 Oct 2026 15:55:44 +1030 Subject: [PATCH 3/4] ESP/TAS5805: Initialize all I2C device config fields Explicitly initialise scl_wait_us and flags so the build is clean under -Wmissing-designated-field-initializers. A zero timeout uses the driver default. --- esp/speaker-netsender/components/tas5805/tas5805.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/esp/speaker-netsender/components/tas5805/tas5805.cpp b/esp/speaker-netsender/components/tas5805/tas5805.cpp index 6820b4d..c1ce7d3 100644 --- a/esp/speaker-netsender/components/tas5805/tas5805.cpp +++ b/esp/speaker-netsender/components/tas5805/tas5805.cpp @@ -77,6 +77,8 @@ TAS5805::TAS5805(i2c_master_bus_handle_t i2c_bus_handle, i2s_chan_handle_t i2s_t .dev_addr_length = I2C_ADDR_BIT_LEN_7, .device_address = static_cast(CONFIG_AMP_I2C_ADDRESS), .scl_speed_hz = CONFIG_AMP_I2C_CLOCK_SPEED, + .scl_wait_us = 0, // Use the driver default timeout. + .flags = {}, }; // Add the device to the bus. From ff05879da0e7e2727a175574c15f9ab169046d60 Mon Sep 17 00:00:00 2001 From: David Sutton Date: Thu, 29 Oct 2026 15:56:52 +1030 Subject: [PATCH 4/4] ESP/Netsender: Size config parameter buffer from both field limits Avoid a build-time assertion when the pin count is configured low by sizing the temporary config buffer to the larger of the IO and WiFi field lengths. --- esp/speaker-netsender/components/netsender/netsender.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/esp/speaker-netsender/components/netsender/netsender.cpp b/esp/speaker-netsender/components/netsender/netsender.cpp index 7f93d3c..2d6e4ea 100644 --- a/esp/speaker-netsender/components/netsender/netsender.cpp +++ b/esp/speaker-netsender/components/netsender/netsender.cpp @@ -450,8 +450,8 @@ esp_err_t Netsender::req_config() // Parse the incoming config from the fixed response buffer. A single // buffer is large enough for every config field. - static_assert(NETSENDER_IO_SIZE >= NETSENDER_WIFI_SIZE, "config parameter buffer too small"); - char param[NETSENDER_IO_SIZE]; + constexpr auto PARAM_BUF_LEN = NETSENDER_IO_SIZE > NETSENDER_WIFI_SIZE ? NETSENDER_IO_SIZE : NETSENDER_WIFI_SIZE; + char param[PARAM_BUF_LEN]; int32_t number = 0; if (netsender_extract_json(resp_buf, "mp", param, sizeof(param)) && parse_int(param, number) &&