Skip to content

Commit

Permalink
Merge pull request #2769 from particle-iot/discard-bad-resumed-ota/sc…
Browse files Browse the repository at this point in the history
…-127555

Resumable OTA fixes
  • Loading branch information
scott-brust authored May 28, 2024
2 parents b3b92e3 + 210c58e commit 0e34f23
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 5 deletions.
32 changes: 27 additions & 5 deletions communication/src/firmware_update.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,11 @@ ProtocolError FirmwareUpdate::responseAck(Message* msg, bool* handled) {
LOG(INFO, "Duplicate chunks: %u", stats_.duplicateChunks);
LOG(INFO, "Out-of-order chunks: %u", stats_.outOfOrderChunks);
LOG(INFO, "Applying firmware update");
r = callbacks_->finish_firmware_update(0);
FirmwareUpdateFlags flags;
if (discardData_) {
flags |= FirmwareUpdateFlag::DISCARD_DATA;
}
r = callbacks_->finish_firmware_update(flags.value());
if (r < 0) {
LOG(ERROR, "Failed to apply firmware update: %d", r);
cancelUpdate();
Expand Down Expand Up @@ -361,22 +365,34 @@ int FirmwareUpdate::handleFinishRequest(const CoapMessageDecoder& d, CoapMessage
FirmwareUpdateFlags flags;
if (discardData) {
LOG(INFO, "Discard data: %u", (unsigned)discardData);
flags |= FirmwareUpdateFlag::DISCARD_DATA;
}
if (cancelUpdate) {
LOG(INFO, "Cancel update: %u", (unsigned)cancelUpdate);
LOG(INFO, "Cancelling firmware update");
LOG(WARN, "Cancelling firmware update");
flags |= FirmwareUpdateFlag::CANCEL;
if (discardData) {
flags |= FirmwareUpdateFlag::DISCARD_DATA;
}
} else {
if (fileOffset_ != fileSize_) {
SYSTEM_ERROR_MESSAGE("Incomplete file transfer");
return SYSTEM_ERROR_PROTOCOL;
}
LOG(INFO, "Validating firmware update");
flags |= FirmwareUpdateFlag::VALIDATE_ONLY;
// The DISCARD_DATA flag has no effect when combined with VALIDATE_ONLY. The flag will be
// set later, when a response for the UpdateFinish request is received
discardData_ = discardData;
}
const auto t1 = millis();
CHECK(callbacks_->finish_firmware_update(flags.value()));
int r = callbacks_->finish_firmware_update(flags.value());
if (r < 0) {
if (!cancelUpdate) {
// Make sure the module data is going to be discarded
discardData_ = true;
}
return r;
}
stats_.processingTime += millis() - t1;
e->type(d.type());
e->code(CoapCode::CHANGED);
Expand Down Expand Up @@ -739,7 +755,11 @@ int FirmwareUpdate::sendEmptyAck(Message* msg, CoapType type, CoapMessageId id)

void FirmwareUpdate::cancelUpdate() {
if (updating_) {
const int r = callbacks_->finish_firmware_update((unsigned)FirmwareUpdateFlag::CANCEL);
FirmwareUpdateFlags flags = FirmwareUpdateFlag::CANCEL;
if (discardData_) {
flags |= FirmwareUpdateFlag::DISCARD_DATA;
}
const int r = callbacks_->finish_firmware_update(flags.value());
if (r < 0) {
LOG(ERROR, "Failed to cancel the update: %d", r);
}
Expand All @@ -765,6 +785,8 @@ void FirmwareUpdate::reset() {
finishRespId_ = -1;
errorRespId_ = -1;
hasGaps_ = false;
discardData_ = false;
// updating_ is cleared separately
}

} // namespace protocol
Expand Down
1 change: 1 addition & 0 deletions communication/src/firmware_update.h
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ class FirmwareUpdate {
int finishRespId_; // Message ID of the UpdateFinish response
int errorRespId_; // Message ID of the last confirmable error response sent to the server
bool hasGaps_; // Whether the sequence of received chunks has gaps
bool discardData_; // Whether to discard the cached module data after the update
bool updating_; // Whether an update is in progress

ProtocolError handleRequest(Message* msg, RequestHandlerFn handler);
Expand Down

0 comments on commit 0e34f23

Please sign in to comment.