Skip to content

Commit

Permalink
New method returning the native ESP-IDF image descriptors
Browse files Browse the repository at this point in the history
  • Loading branch information
ivmarkov committed Jan 30, 2025
1 parent 1143277 commit 2a00ac4
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 5 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Fixed
- Fix wrong BT configuration version on the c6 (issue #556)

### Added
- OTA: New method - `EspFirmwareInfoLoad::fetch_native` - returning the full native ESP-IDF image descriptor structures

## [0.51.0] - 2025-01-15

### Breaking
Expand Down
53 changes: 48 additions & 5 deletions src/ota.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,37 +149,80 @@ impl FirmwareInfoLoader for EspFirmwareInfoLoader {
}
}

/// Native ESP-IDF firmware information
#[derive(Debug, Clone)]
pub struct EspNativeFirmwareInfo<'a> {
/// Image header
pub image_header: &'a esp_image_header_t,
/// Segment header
pub segment_header: &'a esp_image_segment_header_t,
/// Application description
pub app_desc: &'a esp_app_desc_t,
}

/// A firmware info loader that tries to read the firmware info directly
/// from a user-supplied buffer which can be re-used for other purposes afterwards.
///
/// This is a more efficient version of the now-deprecated `EspFirmwareInfoLoader`.
pub struct EspFirmwareInfoLoad;

impl EspFirmwareInfoLoad {
/// Fetches firmware information from the firmware binary data chunk loaded so far.
/// Fetches the native ESP-IDF firmware information from the firmware binary data chunk loaded so far.
///
/// Returns `true` if the information was successfully fetched.
/// Returns `false` if the firmware data has not been loaded completely yet.
pub fn fetch(&self, data: &[u8], info: &mut FirmwareInfo) -> Result<bool, EspIOError> {
/// Returns `Some(EspNativeFirmwareInfo)` if the information was successfully fetched.
/// Returns `None` if the firmware data has not been loaded completely yet.
pub fn fetch_native<'a>(&self, data: &'a [u8]) -> Option<EspNativeFirmwareInfo<'a>> {
let loaded = data.len()
>= mem::size_of::<esp_image_header_t>()
+ mem::size_of::<esp_image_segment_header_t>()
+ mem::size_of::<esp_app_desc_t>();

if loaded {
let image_header_slice = &data[..mem::size_of::<esp_image_header_t>()];
let image_segment_header_slice = &data[mem::size_of::<esp_image_header_t>()
..mem::size_of::<esp_image_header_t>()
+ mem::size_of::<esp_image_segment_header_t>()];
let app_desc_slice = &data[mem::size_of::<esp_image_header_t>()
+ mem::size_of::<esp_image_segment_header_t>()
..mem::size_of::<esp_image_header_t>()
+ mem::size_of::<esp_image_segment_header_t>()
+ mem::size_of::<esp_app_desc_t>()];

let image_header = unsafe {
(image_header_slice.as_ptr() as *const esp_image_header_t)
.as_ref()
.unwrap()
};

let segment_header = unsafe {
(image_segment_header_slice.as_ptr() as *const esp_image_segment_header_t)
.as_ref()
.unwrap()
};

let app_desc = unsafe {
(app_desc_slice.as_ptr() as *const esp_app_desc_t)
.as_ref()
.unwrap()
};

Self::load_firmware_info(info, app_desc)?;
Some(EspNativeFirmwareInfo {
image_header,
segment_header,
app_desc,
})
} else {
None
}
}

/// Fetches firmware information from the firmware binary data chunk loaded so far.
///
/// Returns `true` if the information was successfully fetched.
/// Returns `false` if the firmware data has not been loaded completely yet.
pub fn fetch(&self, data: &[u8], info: &mut FirmwareInfo) -> Result<bool, EspIOError> {
if let Some(native_info) = self.fetch_native(data) {
Self::load_firmware_info(info, native_info.app_desc)?;

Ok(true)
} else {
Expand Down

0 comments on commit 2a00ac4

Please # to comment.