From 908fda824096caa0189edc7316a1eba2f84e609e Mon Sep 17 00:00:00 2001 From: Michael Sauer Date: Sun, 13 Sep 2026 00:29:12 +0200 Subject: [PATCH] fix: OTA-Log im Recovery-Skip-Pfad nicht mehr als Fehlschlag ausgeben MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Auf dem Überspring-Pfad (Recovery lehnt ein Image ab, weil es bereits die laufende Version trägt) bleibt s_error absichtlich NULL, landete aber trotzdem in printf("ota: failed (rc=%d, %s)\r\n", rc, s_error) - ein Nullzeiger an %s ist undefiniertes Verhalten und wurde bislang nur zufällig von newlib als "(null)" abgefangen. Zusätzlich widersprach die Meldung "failed" der direkt folgenden Zeile "recovery: image already up to date, continuing normal boot". ota_task() unterscheidet jetzt explizit zwischen dem Skip-Fall (eigene, ehrliche "ota: skipped"-Zeile) und dem echten Fehlschlag (bestehende "ota: failed"-Zeile, weiterhin mit dem "download"-Fallback für ein leeres s_error). rc bleibt reiner Diagnosewert im Log, da das SDK den Transfer in beiden Fällen abbricht, sobald der Trailer-Hook das Image ablehnt. Restliche Leser von s_error/nl_ota_last_error() (nl_recovery.c, nl_api.c) waren bereits NULL-sicher und mussten nicht angepasst werden. Co-Authored-By: Claude Sonnet 5 --- src/sys/nl_ota.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/sys/nl_ota.c b/src/sys/nl_ota.c index 6935946..39b4851 100644 --- a/src/sys/nl_ota.c +++ b/src/sys/nl_ota.c @@ -94,10 +94,19 @@ static void ota_task(void *arg) (void)arg; log_url(s_url); rc = t_http_fwup(s_url); - /* Only reached on failure - the SDK resets the chip itself after a good image. */ - if (s_error == NULL && !s_skipped) - s_error = "download"; - printf("ota: failed (rc=%d, %s)\r\n", rc, s_error); + /* Only reached on failure or a deliberate skip - the SDK resets the chip itself after a good + * image. rc is not a reliable success/failure signal here: the SDK aborts the transfer as + * soon as the trailer hook returns false, which happens both for a real rejection and for the + * deliberate "recovery image already up to date" skip. s_error/s_skipped are what actually + * distinguish the two, so branch on those instead of folding everything into one printf that + * would risk passing a NULL s_error to %s. */ + if (s_skipped) { + printf("ota: skipped (rc=%d, image already up to date)\r\n", rc); + } else { + if (s_error == NULL) + s_error = "download"; + printf("ota: failed (rc=%d, %s)\r\n", rc, s_error); + } { nl_settings_t *s; nl_app_lock();