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();