Skip to content

Commit 0e34f23

Browse files
authored
Merge pull request #2769 from particle-iot/discard-bad-resumed-ota/sc-127555
Resumable OTA fixes
2 parents b3b92e3 + 210c58e commit 0e34f23

File tree

2 files changed

+28
-5
lines changed

2 files changed

+28
-5
lines changed

communication/src/firmware_update.cpp

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,11 @@ ProtocolError FirmwareUpdate::responseAck(Message* msg, bool* handled) {
114114
LOG(INFO, "Duplicate chunks: %u", stats_.duplicateChunks);
115115
LOG(INFO, "Out-of-order chunks: %u", stats_.outOfOrderChunks);
116116
LOG(INFO, "Applying firmware update");
117-
r = callbacks_->finish_firmware_update(0);
117+
FirmwareUpdateFlags flags;
118+
if (discardData_) {
119+
flags |= FirmwareUpdateFlag::DISCARD_DATA;
120+
}
121+
r = callbacks_->finish_firmware_update(flags.value());
118122
if (r < 0) {
119123
LOG(ERROR, "Failed to apply firmware update: %d", r);
120124
cancelUpdate();
@@ -361,22 +365,34 @@ int FirmwareUpdate::handleFinishRequest(const CoapMessageDecoder& d, CoapMessage
361365
FirmwareUpdateFlags flags;
362366
if (discardData) {
363367
LOG(INFO, "Discard data: %u", (unsigned)discardData);
364-
flags |= FirmwareUpdateFlag::DISCARD_DATA;
365368
}
366369
if (cancelUpdate) {
367370
LOG(INFO, "Cancel update: %u", (unsigned)cancelUpdate);
368-
LOG(INFO, "Cancelling firmware update");
371+
LOG(WARN, "Cancelling firmware update");
369372
flags |= FirmwareUpdateFlag::CANCEL;
373+
if (discardData) {
374+
flags |= FirmwareUpdateFlag::DISCARD_DATA;
375+
}
370376
} else {
371377
if (fileOffset_ != fileSize_) {
372378
SYSTEM_ERROR_MESSAGE("Incomplete file transfer");
373379
return SYSTEM_ERROR_PROTOCOL;
374380
}
375381
LOG(INFO, "Validating firmware update");
376382
flags |= FirmwareUpdateFlag::VALIDATE_ONLY;
383+
// The DISCARD_DATA flag has no effect when combined with VALIDATE_ONLY. The flag will be
384+
// set later, when a response for the UpdateFinish request is received
385+
discardData_ = discardData;
377386
}
378387
const auto t1 = millis();
379-
CHECK(callbacks_->finish_firmware_update(flags.value()));
388+
int r = callbacks_->finish_firmware_update(flags.value());
389+
if (r < 0) {
390+
if (!cancelUpdate) {
391+
// Make sure the module data is going to be discarded
392+
discardData_ = true;
393+
}
394+
return r;
395+
}
380396
stats_.processingTime += millis() - t1;
381397
e->type(d.type());
382398
e->code(CoapCode::CHANGED);
@@ -739,7 +755,11 @@ int FirmwareUpdate::sendEmptyAck(Message* msg, CoapType type, CoapMessageId id)
739755

740756
void FirmwareUpdate::cancelUpdate() {
741757
if (updating_) {
742-
const int r = callbacks_->finish_firmware_update((unsigned)FirmwareUpdateFlag::CANCEL);
758+
FirmwareUpdateFlags flags = FirmwareUpdateFlag::CANCEL;
759+
if (discardData_) {
760+
flags |= FirmwareUpdateFlag::DISCARD_DATA;
761+
}
762+
const int r = callbacks_->finish_firmware_update(flags.value());
743763
if (r < 0) {
744764
LOG(ERROR, "Failed to cancel the update: %d", r);
745765
}
@@ -765,6 +785,8 @@ void FirmwareUpdate::reset() {
765785
finishRespId_ = -1;
766786
errorRespId_ = -1;
767787
hasGaps_ = false;
788+
discardData_ = false;
789+
// updating_ is cleared separately
768790
}
769791

770792
} // namespace protocol

communication/src/firmware_update.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ class FirmwareUpdate {
165165
int finishRespId_; // Message ID of the UpdateFinish response
166166
int errorRespId_; // Message ID of the last confirmable error response sent to the server
167167
bool hasGaps_; // Whether the sequence of received chunks has gaps
168+
bool discardData_; // Whether to discard the cached module data after the update
168169
bool updating_; // Whether an update is in progress
169170

170171
ProtocolError handleRequest(Message* msg, RequestHandlerFn handler);

0 commit comments

Comments
 (0)