use crate::error::FpgadError;
use crate::softeners::error::FpgadSoftenerError;
use log::trace;
use std::fs;
use std::path::Path;
pub fn extract_firmware_name(dtbo_path: &Path) -> Result<String, FpgadError> {
trace!("Extracting firmware-name from '{}'", dtbo_path.display());
let dtb_data = fs::read(dtbo_path).map_err(|e| {
FpgadSoftenerError::DfxMgr(format!(
"Failed to read dtbo file '{}': {}",
dtbo_path.display(),
e
))
})?;
let fdt = fdt::Fdt::new(&dtb_data).map_err(|e| {
FpgadSoftenerError::DfxMgr(format!(
"Failed to parse dtbo file '{}': {:?}",
dtbo_path.display(),
e
))
})?;
for node in fdt.all_nodes() {
if let Some(firmware_name_prop) = node.property("firmware-name") {
let value = firmware_name_prop.value;
let end = value.iter().position(|&b| b == 0).unwrap_or(value.len());
let firmware_name = std::str::from_utf8(&value[..end]).map_err(|e| {
FpgadSoftenerError::DfxMgr(format!(
"Failed to parse firmware-name as UTF-8 string: {}",
e
))
})?;
trace!("Found firmware-name='{}' in dtbo", firmware_name);
return Ok(firmware_name.to_string());
}
}
Err(FpgadSoftenerError::DfxMgr(format!(
"`firmware-name` property not found in dtbo file '{}'",
dtbo_path.display()
))
.into())
}
#[cfg(test)]
mod tests {
use crate::softeners::xilinx_dfx_mgr::xilinx_dfx_mgr_helpers::extract_firmware_name;
use std::path::PathBuf;
#[test]
fn test_extract_firmware_name_k26() {
let test_dtbo = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("tests/test_data/k26-starter-kits/k26_starter_kits.dtbo");
if test_dtbo.exists() {
let result = extract_firmware_name(&test_dtbo);
assert!(result.is_ok());
assert_eq!(result.unwrap(), "k26-starter-kits.bit.bin");
}
}
#[test]
fn test_extract_firmware_name_k24() {
let test_dtbo = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("tests/test_data/k24-starter-kits/k24_starter_kits.dtbo");
if test_dtbo.exists() {
let result = extract_firmware_name(&test_dtbo);
assert!(result.is_ok());
assert_eq!(result.unwrap(), "k24-starter-kits.bit.bin");
}
}
}