ota: perform the happy path processing in ota_finalize()
What changed, and why it matters
This commit moves the 'success' handling of firmware updates (sending an OK reply, showing a success message, and rebooting) into a shared helper function called ota_finalize(). Previously, this success logic was duplicated in two places after calling ota_finalize(). The change is a code cleanup and does not appear to alter security behavior, but it does mean the success path now lives inside the finalization routine rather than after it returns.
Review the full ota_finalize() implementation to confirm that all error paths return before the success reboot logic, and that no caller relies on post-finalize cleanup code on success. No immediate action required beyond normal regression testing of OTA flows.
Security signals we found
Refactoring of OTA finalization success path
No new security controls added
No change to partition selection or signature verification logic visible in diff
Happy path now exits via esp_restart() inside helper rather than caller
Evidence from the diff
The patch refactors OTA success handling. Both ota_process() and ota_delta_process() previously called ota_finalize(joctx), then checked joctx->ota_return_status, sent an OK reply, logged success, displayed a message, delayed, and rebooted. Now ota_finalize() takes an additional jade_process_t* process argument and performs the OK reply, logging, display, delay, and reboot internally on success. Callers now only handle the error path in their cleanup labels. Function signature updated in ota_util.h. No new validation, authentication, or rollback logic is introduced.
Changed components
main/process/ota.cmain/process/ota_delta.cmain/process/ota_util.cmain/process/ota_util.hInspect captured patch +19 / −32
diff --git a/main/process/ota.c b/main/process/ota.c
index 5672a7a..7bab16b 100644
--- a/main/process/ota.c
+++ b/main/process/ota.c
@@ -128,7 +128,7 @@ void ota_process(void* process_ptr)
// If all good with the upload do all final checks and then finalise the ota
// and set the new boot partition, etc.
- ota_finalize(joctx);
+ ota_finalize(process, joctx);
// Send final message reply with final status
if (joctx->ota_return_status != OTA_SUCCESS) {
@@ -139,22 +139,10 @@ void ota_process(void* process_ptr)
goto cleanup;
}
- jade_process_reply_to_message_ok(process);
- JADE_LOGI("Success");
-
cleanup:
- // If ota has been successful show message and reboot.
- // If error, show error-message and await user acknowledgement.
- if (joctx->ota_return_status == OTA_SUCCESS) {
- JADE_LOGW("OTA successful - rebooting");
-
- const char* message[] = { "Upgrade successful!" };
- display_message_activity(message, 1);
-
- vTaskDelay(2500 / portTICK_PERIOD_MS);
- esp_restart();
- } else {
+ // Show error-message and await user acknowledgement.
+ if (joctx->ota_return_status != OTA_SUCCESS) {
JADE_LOGE("OTA error %u: %s", joctx->ota_return_status, ota_get_status_text(joctx->ota_return_status));
// If we get here and we have not finished loading the data, send an error message
diff --git a/main/process/ota_delta.c b/main/process/ota_delta.c
index a54a5ce..9bfe7a5 100644
--- a/main/process/ota_delta.c
+++ b/main/process/ota_delta.c
@@ -202,7 +202,7 @@ void ota_delta_process(void* process_ptr)
// If all good with the upload do all final checks and then finalise the ota
// and set the new boot partition, etc.
- ota_finalize(joctx);
+ ota_finalize(process, joctx);
// Send final message reply with final status
if (joctx->ota_return_status != OTA_SUCCESS) {
@@ -213,22 +213,10 @@ void ota_delta_process(void* process_ptr)
goto cleanup;
}
- jade_process_reply_to_message_ok(process);
- JADE_LOGI("Success");
-
cleanup:
- // If ota has been successful show message and reboot.
- // If error, show error-message and await user acknowledgement.
- if (joctx->ota_return_status == OTA_SUCCESS) {
- JADE_LOGW("OTA successful - rebooting");
-
- const char* message[] = { "Upgrade successful!" };
- display_message_activity(message, 1);
-
- vTaskDelay(2500 / portTICK_PERIOD_MS);
- esp_restart();
- } else {
+ // Show error-message and await user acknowledgement.
+ if (joctx->ota_return_status != OTA_SUCCESS) {
JADE_LOGE("OTA error %u: %s", joctx->ota_return_status, ota_get_status_text(joctx->ota_return_status));
// If we get here and we have not finished loading the data, send an error message
diff --git a/main/process/ota_util.c b/main/process/ota_util.c
index bb3b97e..9701030 100644
--- a/main/process/ota_util.c
+++ b/main/process/ota_util.c
@@ -246,7 +246,7 @@ cleanup:
return joctx;
}
-void ota_finalize(jade_ota_ctx_t* joctx)
+void ota_finalize(jade_process_t* process, jade_ota_ctx_t* joctx)
{
JADE_ASSERT(joctx);
@@ -298,6 +298,17 @@ void ota_finalize(jade_ota_ctx_t* joctx)
joctx->ota_return_status = OTA_ERR_SETPARTITION;
return;
}
+
+ // OTA completed without errors. send an ok and reboot
+ jade_process_reply_to_message_ok(process);
+ JADE_LOGI("Success");
+ JADE_LOGW("OTA successful - rebooting");
+
+ const char* message[] = { "Upgrade successful!" };
+ display_message_activity(message, 1);
+
+ vTaskDelay(2500 / portTICK_PERIOD_MS);
+ esp_restart();
}
// NOTE: 'dest' is assumed to be at least as long as 'strlen(src)'
diff --git a/main/process/ota_util.h b/main/process/ota_util.h
index 2d2e2a4..0c1fe99 100644
--- a/main/process/ota_util.h
+++ b/main/process/ota_util.h
@@ -78,7 +78,7 @@ void handle_in_bin_data(void* ctx, uint8_t* data, size_t rawsize);
jade_ota_ctx_t* ota_init(jade_process_t* process, bool is_delta);
void ota_user_validate(jade_ota_ctx_t* joctx, const uint8_t* uncompressed);
-void ota_finalize(jade_ota_ctx_t* joctx);
+void ota_finalize(jade_process_t* process, jade_ota_ctx_t* joctx);
const char* ota_get_status_text(ota_status_t status);
#endif /* JADE_OTA_UTIL_H_ */
Why this scored 28/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.