mirror of
https://github.com/ALLFATHER-BV/wadamesh.git
synced 2026-11-11 11:17:34 +00:00
touch: on-device update resumes a dropped download (#689)
A connection that stalled or dropped part way failed the update with "short read" and the user had to start again, sometimes several times. The download now continues from where it stopped with a Range request, up to 3 times, and only appends a 206 for exactly the remaining bytes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
cec1431c7a
commit
cbeb518435
1 file changed
+40
-19
+40
-19
@@ -35499,35 +35499,56 @@ static void otaWorkerRun(WiFiClient& client, HTTPClient& http) {
|
||||
// slow start starved IDLE0 on this core-0 worker and the 5 s task watchdog
|
||||
// rebooted the device, "stuck at 0%, then a restart" (#689). Same loop as the SD
|
||||
// download below: wait with vTaskDelay, give up after 15 s without data.
|
||||
auto* stream = http.getStreamPtr(); // NetworkClient* on arduino 3.x (P4: C6Client behind it)
|
||||
//
|
||||
// A connection that drops or stalls part way is picked up where it stopped with a Range
|
||||
// request, up to 3 times, instead of failing with "short read" and starting over (#689:
|
||||
// "after re-trying a few times, device was updated").
|
||||
size_t written = 0;
|
||||
{
|
||||
size_t bufsz = 4096;
|
||||
uint8_t* buf = (uint8_t*)heap_caps_malloc(bufsz, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
|
||||
if (!buf) { bufsz = 1024; buf = (uint8_t*)heap_caps_malloc(bufsz, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); }
|
||||
unsigned long last_data = millis();
|
||||
while (buf && stream && written < (size_t)len) {
|
||||
const int avail = stream->available();
|
||||
if (avail <= 0) {
|
||||
if (!http.connected() || (millis() - last_data) > 15000) break;
|
||||
vTaskDelay(pdMS_TO_TICKS(10));
|
||||
continue;
|
||||
bool write_failed = false;
|
||||
for (int resume = 0; buf && !write_failed; ++resume) {
|
||||
auto* stream = http.getStreamPtr(); // NetworkClient* on arduino 3.x (P4: C6Client behind it)
|
||||
unsigned long last_data = millis();
|
||||
while (stream && written < (size_t)len) {
|
||||
const int avail = stream->available();
|
||||
if (avail <= 0) {
|
||||
if (!http.connected() || (millis() - last_data) > 15000) break;
|
||||
vTaskDelay(pdMS_TO_TICKS(10));
|
||||
continue;
|
||||
}
|
||||
const size_t want = ((size_t)avail > bufsz) ? bufsz : (size_t)avail;
|
||||
const int n = stream->read(buf, want);
|
||||
if (n <= 0) {
|
||||
if ((millis() - last_data) > 15000) break;
|
||||
vTaskDelay(pdMS_TO_TICKS(5));
|
||||
continue;
|
||||
}
|
||||
last_data = millis();
|
||||
if (Update.write(buf, (size_t)n) != (size_t)n) { write_failed = true; break; } // reported below
|
||||
written += (size_t)n;
|
||||
vTaskDelay(1); // let IDLE0 (and Wi-Fi) run between blocks
|
||||
}
|
||||
const size_t want = ((size_t)avail > bufsz) ? bufsz : (size_t)avail;
|
||||
const int n = stream->read(buf, want);
|
||||
if (n <= 0) {
|
||||
if ((millis() - last_data) > 15000) break;
|
||||
vTaskDelay(pdMS_TO_TICKS(5));
|
||||
continue;
|
||||
http.end();
|
||||
if (written >= (size_t)len || write_failed || resume >= 3) break;
|
||||
Serial.printf("[OTA] stopped at %u/%d, resuming (%d)\n", (unsigned)written, len, resume + 1);
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
if (!http.begin(client, url)) break;
|
||||
char range[40];
|
||||
snprintf(range, sizeof range, "bytes=%u-", (unsigned)written);
|
||||
http.addHeader("Range", range);
|
||||
const int rc = http.GET();
|
||||
// Only a 206 for exactly the rest is safe to append; anything else ends the update.
|
||||
if (rc != 206 || http.getSize() != (int)((size_t)len - written)) {
|
||||
Serial.printf("[OTA] resume -> %d (%d bytes)\n", rc, http.getSize());
|
||||
http.end();
|
||||
break;
|
||||
}
|
||||
last_data = millis();
|
||||
if (Update.write(buf, (size_t)n) != (size_t)n) break; // flash write failed: reported below
|
||||
written += (size_t)n;
|
||||
vTaskDelay(1); // let IDLE0 (and Wi-Fi) run between blocks
|
||||
}
|
||||
if (buf) heap_caps_free(buf);
|
||||
}
|
||||
http.end();
|
||||
if (written != (size_t)len) {
|
||||
snprintf(s_ota_msg, sizeof s_ota_msg, "short read %u/%d", (unsigned)written, len);
|
||||
Update.abort(); s_ota_state = 3; return;
|
||||
|
||||
Reference in new issue
Block a user