enable cancel mid-flight in an HTTPS firmware upload

This commit is contained in:
proddy
2026-06-06 16:35:40 +02:00
parent b1bc8110cc
commit 791285e7f4
3 changed files with 36 additions and 4 deletions

View File

@@ -145,9 +145,21 @@ const SystemMonitor = () => {
{LL.PLEASE_WAIT()}…
</Typography>
{isUploading && (
<Box sx={{ width: '100%', pl: 2, pr: 2, py: 2 }}>
<LinearProgressWithLabel value={progressValue} />
</Box>
<>
<Box sx={{ width: '100%', pl: 2, pr: 2, py: 2 }}>
<LinearProgressWithLabel value={progressValue} />
</Box>
<Button
sx={{ ml: 2, mt: 2 }}
startIcon={<CancelIcon />}
variant="outlined"
color="secondary"
onClick={onCancel}
>
{LL.CANCEL()}
</Button>
</>
)}
</>
)}

View File

@@ -3149,6 +3149,18 @@ bool System::uploadFirmwareURL(const char * url) {
int last_pct = -1;
while (total_read < (size_t)firmware_size) {
// a cancel is signalled by the WebUI dropping the status below UPLOADING (back to NORMAL)
// via the systemStatus action, which runs on the AsyncTCP task while we're blocked here
if (EMSESP::system_.systemStatus() < SYSTEM_STATUS::SYSTEM_STATUS_UPLOADING) {
LOG_WARNING("Firmware upload cancelled at %u of %d bytes", (unsigned)total_read, firmware_size);
Update.abort(); // release the OTA partition handle so a later attempt can start cleanly
ssl_client.stop(); // drop the connection
saved_url.clear(); // prevent it from downloading again
EMSESP::system_.systemStatus(SYSTEM_STATUS::SYSTEM_STATUS_NORMAL);
Shell::loop_all(); // flush log buffers so the cancel message shows in the console
return true; // not an error - don't trigger the failure/reset path in emsesp.cpp
}
// wait for some data or for the connection to drop
uint32_t wait_start = millis();
while (!stream->available()) {
@@ -3158,10 +3170,18 @@ bool System::uploadFirmwareURL(const char * url) {
if (millis() - wait_start > READ_TIMEOUT_MS) {
break;
}
// also bail out promptly if a cancel arrives mid-stall
if (EMSESP::system_.systemStatus() < SYSTEM_STATUS::SYSTEM_STATUS_UPLOADING) {
break;
}
delay(1);
}
if (!stream->available()) {
// if the inner wait broke because of a cancel, loop back so the top-of-loop handler runs
if (EMSESP::system_.systemStatus() < SYSTEM_STATUS::SYSTEM_STATUS_UPLOADING) {
continue;
}
LOG_ERROR("Firmware upload failed - read stalled at %u of %d bytes", (unsigned)total_read, firmware_size);
EMSESP::system_.systemStatus(SYSTEM_STATUS::SYSTEM_STATUS_ERROR_UPLOAD);
return false;

View File

@@ -358,7 +358,7 @@ class System {
static uint32_t heap_mem_;
static uint32_t min_free_mem_;
uint8_t systemStatus_; // uses SYSTEM_STATUS enum
volatile uint8_t systemStatus_; // uses SYSTEM_STATUS enum - written from the AsyncTCP task (e.g. cancel) and read from the main loop during OTA
void set_partition_install_date();