From 56e6b6bee6bd6087b35857e8aa1a011f6e83f703 Mon Sep 17 00:00:00 2001
From: Badr Bouslikhin <bouslikhin.badr@gmail.com>
Date: Mon, 12 Feb 2024 23:24:21 +0100
Subject: [PATCH] refactor(boot): move page erase index out of state

---
 embassy-boot/src/firmware_updater/asynch.rs   | 14 +++++---------
 embassy-boot/src/firmware_updater/blocking.rs | 14 +++++---------
 2 files changed, 10 insertions(+), 18 deletions(-)

diff --git a/embassy-boot/src/firmware_updater/asynch.rs b/embassy-boot/src/firmware_updater/asynch.rs
index d31eff005..b76668136 100644
--- a/embassy-boot/src/firmware_updater/asynch.rs
+++ b/embassy-boot/src/firmware_updater/asynch.rs
@@ -13,6 +13,7 @@ use crate::{FirmwareUpdaterError, State, BOOT_MAGIC, DFU_DETACH_MAGIC, STATE_ERA
 pub struct FirmwareUpdater<'d, DFU: NorFlash, STATE: NorFlash> {
     dfu: DFU,
     state: FirmwareState<'d, STATE>,
+    last_erased_dfu_page_index: Option<usize>,
 }
 
 #[cfg(target_os = "none")]
@@ -56,6 +57,7 @@ impl<'d, DFU: NorFlash, STATE: NorFlash> FirmwareUpdater<'d, DFU, STATE> {
         Self {
             dfu: config.dfu,
             state: FirmwareState::new(config.state, aligned),
+            last_erased_dfu_page_index: None,
         }
     }
 
@@ -72,7 +74,7 @@ impl<'d, DFU: NorFlash, STATE: NorFlash> FirmwareUpdater<'d, DFU, STATE> {
     /// proceed with updating the firmware as it must be signed with a
     /// corresponding private key (otherwise it could be malicious firmware).
     ///
-    /// Mark to trigger firmware swap on next boot if verify suceeds.
+    /// Mark to trigger firmware swap on next boot if verify succeeds.
     ///
     /// If the "ed25519-salty" feature is set (or another similar feature) then the signature is expected to have
     /// been generated from a SHA-512 digest of the firmware bytes.
@@ -213,14 +215,13 @@ impl<'d, DFU: NorFlash, STATE: NorFlash> FirmwareUpdater<'d, DFU, STATE> {
             let sector_end = sector_start + DFU::ERASE_SIZE;
             // Determine if the current sector needs to be erased before writing.
             let need_erase = self
-                .state
                 .last_erased_dfu_page_index
                 .map_or(true, |last_erased_sector| current_sector != last_erased_sector);
 
             // If the sector needs to be erased, erase it and update the last erased sector index.
             if need_erase {
                 self.dfu.erase(sector_start as u32, sector_end as u32).await?;
-                self.state.last_erased_dfu_page_index = Some(current_sector);
+                self.last_erased_dfu_page_index = Some(current_sector);
             }
 
             // Calculate the size of the data chunk that can be written in the current iteration.
@@ -258,7 +259,6 @@ impl<'d, DFU: NorFlash, STATE: NorFlash> FirmwareUpdater<'d, DFU, STATE> {
 pub struct FirmwareState<'d, STATE> {
     state: STATE,
     aligned: &'d mut [u8],
-    last_erased_dfu_page_index: Option<usize>,
 }
 
 impl<'d, STATE: NorFlash> FirmwareState<'d, STATE> {
@@ -280,11 +280,7 @@ impl<'d, STATE: NorFlash> FirmwareState<'d, STATE> {
     /// and follow the alignment rules for the flash being read from and written to.
     pub fn new(state: STATE, aligned: &'d mut [u8]) -> Self {
         assert_eq!(aligned.len(), STATE::WRITE_SIZE.max(STATE::READ_SIZE));
-        Self {
-            state,
-            aligned,
-            last_erased_dfu_page_index: None,
-        }
+        Self { state, aligned }
     }
 
     // Make sure we are running a booted firmware to avoid reverting to a bad state.
diff --git a/embassy-boot/src/firmware_updater/blocking.rs b/embassy-boot/src/firmware_updater/blocking.rs
index 5b8076f81..eb96a9523 100644
--- a/embassy-boot/src/firmware_updater/blocking.rs
+++ b/embassy-boot/src/firmware_updater/blocking.rs
@@ -13,6 +13,7 @@ use crate::{FirmwareUpdaterError, State, BOOT_MAGIC, DFU_DETACH_MAGIC, STATE_ERA
 pub struct BlockingFirmwareUpdater<'d, DFU: NorFlash, STATE: NorFlash> {
     dfu: DFU,
     state: BlockingFirmwareState<'d, STATE>,
+    last_erased_dfu_page_index: Option<usize>,
 }
 
 #[cfg(target_os = "none")]
@@ -91,6 +92,7 @@ impl<'d, DFU: NorFlash, STATE: NorFlash> BlockingFirmwareUpdater<'d, DFU, STATE>
         Self {
             dfu: config.dfu,
             state: BlockingFirmwareState::new(config.state, aligned),
+            last_erased_dfu_page_index: None,
         }
     }
 
@@ -107,7 +109,7 @@ impl<'d, DFU: NorFlash, STATE: NorFlash> BlockingFirmwareUpdater<'d, DFU, STATE>
     /// proceed with updating the firmware as it must be signed with a
     /// corresponding private key (otherwise it could be malicious firmware).
     ///
-    /// Mark to trigger firmware swap on next boot if verify suceeds.
+    /// Mark to trigger firmware swap on next boot if verify succeeds.
     ///
     /// If the "ed25519-salty" feature is set (or another similar feature) then the signature is expected to have
     /// been generated from a SHA-512 digest of the firmware bytes.
@@ -248,14 +250,13 @@ impl<'d, DFU: NorFlash, STATE: NorFlash> BlockingFirmwareUpdater<'d, DFU, STATE>
             let sector_end = sector_start + DFU::ERASE_SIZE;
             // Determine if the current sector needs to be erased before writing.
             let need_erase = self
-                .state
                 .last_erased_dfu_page_index
                 .map_or(true, |last_erased_sector| current_sector != last_erased_sector);
 
             // If the sector needs to be erased, erase it and update the last erased sector index.
             if need_erase {
                 self.dfu.erase(sector_start as u32, sector_end as u32)?;
-                self.state.last_erased_dfu_page_index = Some(current_sector);
+                self.last_erased_dfu_page_index = Some(current_sector);
             }
 
             // Calculate the size of the data chunk that can be written in the current iteration.
@@ -293,7 +294,6 @@ impl<'d, DFU: NorFlash, STATE: NorFlash> BlockingFirmwareUpdater<'d, DFU, STATE>
 pub struct BlockingFirmwareState<'d, STATE> {
     state: STATE,
     aligned: &'d mut [u8],
-    last_erased_dfu_page_index: Option<usize>,
 }
 
 impl<'d, STATE: NorFlash> BlockingFirmwareState<'d, STATE> {
@@ -315,11 +315,7 @@ impl<'d, STATE: NorFlash> BlockingFirmwareState<'d, STATE> {
     /// and written to.
     pub fn new(state: STATE, aligned: &'d mut [u8]) -> Self {
         assert_eq!(aligned.len(), STATE::WRITE_SIZE);
-        Self {
-            state,
-            aligned,
-            last_erased_dfu_page_index: None,
-        }
+        Self { state, aligned }
     }
 
     // Make sure we are running a booted firmware to avoid reverting to a bad state.