eculocate

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

commit fb59198f70ba9b110ba916b013977d04afba094c
parent 0d86c641344f5ddbdbdff08bfb3f9f7432c82ad1
Author: Daniel Barlow <dan@telent.net>
Date:   Sun, 25 Jan 2026 00:33:14 +0000

remove read_all, shorten using Result

this has made the "can't happen" error messages a bit less helpful
but we will come back to that

Diffstat:
Mecu-esp32/src/ota.rs | 82+++++++++++++++++++++++++++++++++++++++++++------------------------------------
Mecu-esp32/src/wifi.rs | 6++++--
2 files changed, 49 insertions(+), 39 deletions(-)

diff --git a/ecu-esp32/src/ota.rs b/ecu-esp32/src/ota.rs @@ -6,8 +6,10 @@ use ed25519_dalek::{VerifyingKey, Verifier, Signature}; use esp_hal_ota::Ota; use esp_storage::FlashStorage; +use embedded_io_async::{Read,ReadExactError}; use esp_hal::sha; +use core::convert::Infallible; use log::{warn, info, error}; @@ -15,33 +17,38 @@ const ERASE_BLOCK_BYTES : usize = 4096; const ED25519_SIGNATURE_BYTES : usize = 64; const SHA256_BYTES : usize = 32; -async fn read_all(socket: &mut embassy_net::tcp::TcpSocket<'_>, - buf: &mut [u8], - len: usize) -> usize { - let mut n = 0; - while n < len { - match socket.read(&mut buf[n..len]).await { - Ok(0) => { - warn!("read EOF"); - break; - }, - Ok(count) => { - n = n + count; - } - Err(e) => { - warn!("read err {:?}", e); - return 0; // ew - } - } - } - n -} - pub struct Flasher<'a> { ota : Ota<FlashStorage<'a>>, sha_engine : sha::Sha<'a> } +#[derive(Debug)] +pub enum FlashError { + UnexpectedEof, + OtaFailed, + InvalidSignature, + Infallible +} + +impl<E> From<ReadExactError<E>> for FlashError { + fn from(_e : ReadExactError<E>) -> Self { + Self::UnexpectedEof + } +} + +impl From<esp_hal_ota::OtaError> for FlashError { + fn from(_e : esp_hal_ota::OtaError) -> Self { + Self::OtaFailed + } +} + +impl From<Infallible> for FlashError { + fn from(_e : Infallible) -> Self { + Self::Infallible + } +} + + impl Flasher<'_> { pub fn new(flash_peripheral: esp_hal::peripherals::FLASH<'static>, sha_peripheral: esp_hal::peripherals::SHA<'static>) -> Self { @@ -52,7 +59,7 @@ impl Flasher<'_> { Self { ota, sha_engine } } - pub async fn write(&mut self, sock: &mut embassy_net::tcp::TcpSocket<'_>) { + pub async fn write(&mut self, sock: &mut embassy_net::tcp::TcpSocket<'_>) -> Result<(), FlashError> { write_ota(&mut self.ota, &mut self.sha_engine, sock).await } } @@ -60,7 +67,7 @@ impl Flasher<'_> { async fn write_ota(ota : &mut Ota<FlashStorage<'_>>, sha_engine : &mut sha::Sha<'_>, - sock: &mut embassy_net::tcp::TcpSocket<'_>) { + sock: &mut embassy_net::tcp::TcpSocket<'_>) -> Result<(), FlashError> { let mut buf = [0u8; SHA256_BYTES + ERASE_BLOCK_BYTES]; let mut buf_offset = 0; let mut signed; @@ -73,8 +80,8 @@ async fn write_ota(ota : &mut Ota<FlashStorage<'_>>, let mut block0 = [0u8; SHA256_BYTES + 4]; - read_all(sock, &mut signature, ED25519_SIGNATURE_BYTES).await; - read_all(sock, &mut block0, SHA256_BYTES + 4).await; + sock.read_exact(&mut signature).await?; + sock.read_exact(&mut block0[..SHA256_BYTES + 4]).await?; let verifying_key_bytes = include_bytes!("../../pubkey.bin"); let verifying_key: VerifyingKey = VerifyingKey::from_bytes(verifying_key_bytes).expect("verify"); @@ -88,10 +95,8 @@ async fn write_ota(ota : &mut Ota<FlashStorage<'_>>, next_block_hash.clone_from_slice(sha); info!("ota length {}", len); - if let Err(e) = ota.ota_begin(len, 0) { - error!("ota_begin failed {:?}", e); - return; - }; + + ota.ota_begin(len, 0)?; // total payload to expect is image size plus per-block hashes let mut remaining = len + (len/(ERASE_BLOCK_BYTES as u32)+ 1) * (SHA256_BYTES as u32); @@ -123,7 +128,7 @@ async fn write_ota(ota : &mut Ota<FlashStorage<'_>>, _ => () } } - block!(hasher.finish(&mut actual_hash)).expect("hasher.finish expected infallible"); + block!(hasher.finish(&mut actual_hash))?; signed = signed && next_block_hash == actual_hash; @@ -135,7 +140,7 @@ async fn write_ota(ota : &mut Ota<FlashStorage<'_>>, // accept the rest of the update, just don't flash it. warn!("signature invalid with {remaining} left"); } - // + buf_offset = 0; next_block_hash.copy_from_slice(&buf[0..SHA256_BYTES]); } @@ -145,12 +150,15 @@ async fn write_ota(ota : &mut Ota<FlashStorage<'_>>, info!("write {:?}", sock.write(b"BYE\n").await); let _ = sock.flush().await; sock.close(); - if signed && !ota.ota_flush(false, false).is_ok() { - error!("ota failed"); - } - Timer::after_millis(1000).await; - esp_hal::system::software_reset(); + if signed { + ota.ota_flush(false, false)?; + Timer::after_millis(1000).await; + esp_hal::system::software_reset(); + } else { + return Err(FlashError::InvalidSignature) + } } else { warn!("stream ended early or flash failed with {} bytes left", remaining); + Err(FlashError::UnexpectedEof) } } diff --git a/ecu-esp32/src/wifi.rs b/ecu-esp32/src/wifi.rs @@ -38,7 +38,7 @@ use esp_radio::{ use embassy_net::Stack; use embedded_io_async::Read; -use log::{warn, info}; +use log::{warn, info, error}; use crate::mdns; @@ -241,7 +241,9 @@ async fn run_tcp_handler(stack : Stack<'_>, match &buf[0..4] { b"ROM0" => { info!("OTA request"); - flasher.write(&mut socket).await; + if let Err(e) = flasher.write(&mut socket).await { + error!("ota flash failed: {:?}", e); + } }, b"KEY0" => { info!("sessionkey");