From 4e1abca4ea0bded756029f94319968bee386e109 Mon Sep 17 00:00:00 2001 From: DeFiDude <59237470+DeFiDude@users.noreply.github.com> Date: Sat, 25 Jul 2026 01:28:53 -0600 Subject: [PATCH] tools: share RNode capability inspection --- crates/rns-tools/src/commands/rnodeconf.rs | 212 ++++++-- .../rns-tools/src/commands/rnodeconf/model.rs | 505 ++---------------- 2 files changed, 228 insertions(+), 489 deletions(-) diff --git a/crates/rns-tools/src/commands/rnodeconf.rs b/crates/rns-tools/src/commands/rnodeconf.rs index 070f5b4..f5e860e 100644 --- a/crates/rns-tools/src/commands/rnodeconf.rs +++ b/crates/rns-tools/src/commands/rnodeconf.rs @@ -12,7 +12,13 @@ use std::process::ExitCode; use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH}; use clap::{CommandFactory, Parser}; -use rns_interface::{kiss, rnode, rnode_admin}; +use rns_interface::{ + kiss, rnode, rnode_admin, + rnode_capabilities::{ + RNodeCapabilities, RNodeCapabilityParseError, RNodeKnownRadioCapabilities, + RNodeRadioCapabilities, RNodeRadioFamily, parse_rnode_capabilities, rnode_product_name, + }, +}; use rns_tools::RS_RETICULUM_VERSION; // rnodeconf support is staged: safe inspection/config modules are compiled now, @@ -528,36 +534,98 @@ fn print_responses( } fn eeprom_summary_lines(image: &eeprom::EepromImage) -> Vec { - if !image.info_locked() { - return vec!["EEPROM: not provisioned or info lock missing".to_string()]; - } - let identity = image.identity(); - let product = model::product_name(identity.product).unwrap_or("Unknown product"); - let model_info = model::model_info(identity.model); - let model_label = model_info - .map(|info| info.band_label) - .unwrap_or("unknown band"); - let radio_label = model_info.map(|info| info.radio).unwrap_or("unknown radio"); - let checksum_status = if image.checksum_valid() { + let capabilities = match parse_rnode_capabilities(image.bytes()) { + Ok(capabilities) => capabilities, + Err(RNodeCapabilityParseError::InfoNotLocked) => { + return vec!["EEPROM: not provisioned or info lock missing".to_string()]; + } + Err(error) => { + let mut lines = private_eeprom_identity_lines(&identity, false); + lines.push(format!(" Radio capabilities: unavailable ({error})")); + append_startup_config_lines(image, &mut lines); + return lines; + } + }; + + let mut lines = private_eeprom_identity_lines(&identity, true); + append_capability_lines(capabilities, &mut lines); + append_startup_config_lines(image, &mut lines); + lines +} + +fn private_eeprom_identity_lines( + identity: &eeprom::IdentityInfo, + identity_validated: bool, +) -> Vec { + let checksum_status = if identity_validated { "valid" } else { "invalid" }; + let product = if identity_validated { + format!(" Product code: 0x{:02x}", identity.product) + } else { + format!(" Product code: 0x{:02x} (unvalidated)", identity.product) + }; + let model = if identity_validated { + format!(" Model: 0x{:02x}", identity.model) + } else { + format!(" Model code: 0x{:02x} (unvalidated)", identity.model) + }; - let mut lines = vec![ + vec![ "EEPROM: provisioned".to_string(), - format!(" Product: {product} (0x{:02x})", identity.product), - format!( - " Model: 0x{:02x} ({model_label}, {radio_label})", - identity.model - ), + product, + model, format!(" Hardware revision: {}", identity.hw_rev), format!(" Serial: {}", hex::encode(identity.serial.to_be_bytes())), format!(" Manufactured: {}", identity.made), format!(" Identity checksum: {checksum_status}"), - ]; + ] +} +fn append_capability_lines(capabilities: RNodeCapabilities, lines: &mut Vec) { + let product = rnode_product_name(capabilities.product_code()).unwrap_or("Unknown product"); + lines[1] = format!( + " Product: {product} (0x{:02x})", + capabilities.product_code() + ); + lines[2] = format!(" Model: 0x{:02x}", capabilities.model_code()); + + match capabilities.radio() { + RNodeRadioCapabilities::Known(radio) => append_known_radio_lines(radio, lines), + _ => { + lines.push(" Radio capabilities: unavailable for this model".to_string()); + } + } +} + +fn append_known_radio_lines(radio: RNodeKnownRadioCapabilities, lines: &mut Vec) { + lines.extend([ + format!(" Radio family: {}", radio_family_name(radio.family())), + format!( + " Frequency range: {} - {} Hz", + radio.min_frequency_hz(), + radio.max_frequency_hz() + ), + format!(" Maximum TX power: {} dBm", radio.max_tx_power_dbm()), + ]); +} + +fn radio_family_name(family: RNodeRadioFamily) -> &'static str { + match family { + RNodeRadioFamily::Sx1262 => "SX1262", + RNodeRadioFamily::Sx1268 => "SX1268", + RNodeRadioFamily::Sx1276 => "SX1276", + RNodeRadioFamily::Sx1278 => "SX1278", + RNodeRadioFamily::Sx1280 => "SX1280", + RNodeRadioFamily::Sx1262AndSx1280 => "SX1262 + SX1280", + _ => "Unrecognized", + } +} + +fn append_startup_config_lines(image: &eeprom::EepromImage, lines: &mut Vec) { if let Some(radio) = image.radio_config() { let bitrate = rnode::calculate_bitrate(radio.spreading_factor, radio.coding_rate, radio.bandwidth); @@ -573,8 +641,6 @@ fn eeprom_summary_lines(image: &eeprom::EepromImage) -> Vec { } else { lines.push(" Startup mode: Normal (host-controlled)".to_string()); } - - lines } fn rnodeconf_cache_paths() -> Result { @@ -749,6 +815,26 @@ mod tests { ); } + fn provisioned_eeprom(model: u8, radio: Option<&eeprom::RadioConfig>) -> eeprom::EepromImage { + let identity = eeprom::IdentityInfo { + product: model::PRODUCT_RNODE, + model, + hw_rev: 2, + serial: 0x01020304, + made: 0x6553F100, + }; + let mut bytes = vec![0xFF; eeprom::EEPROM_SIZE]; + let mut writes = eeprom::identity_write_frames(&identity); + if let Some(radio) = radio { + writes.extend(eeprom::radio_config_write_frames(radio)); + } + for frame in writes { + let address = frame.payload[0] as usize; + bytes[address] = frame.payload[1]; + } + eeprom::EepromImage::new(bytes).unwrap() + } + #[test] fn info_sequence_matches_upstream_probe_order() { assert_eq!( @@ -999,14 +1085,7 @@ mod tests { } #[test] - fn eeprom_summary_reports_identity_and_radio_config() { - let info = eeprom::IdentityInfo { - product: model::PRODUCT_RNODE, - model: 0xB4, - hw_rev: 2, - serial: 0x01020304, - made: 0x6553F100, - }; + fn eeprom_summary_reports_validated_identity_capabilities_and_radio_config() { let radio = eeprom::RadioConfig { spreading_factor: 7, coding_rate: 5, @@ -1014,28 +1093,85 @@ mod tests { bandwidth: 125000, frequency: 868000000, }; - let mut bytes = vec![0xFF; eeprom::EEPROM_SIZE]; - for frame in eeprom::identity_write_frames(&info) - .into_iter() - .chain(eeprom::radio_config_write_frames(&radio)) - { - let address = frame.payload[0] as usize; - bytes[address] = frame.payload[1]; - } - let image = eeprom::EepromImage::new(bytes).unwrap(); + let image = provisioned_eeprom(0xB4, Some(&radio)); let lines = eeprom_summary_lines(&image); + assert!(lines.iter().any(|line| line == "EEPROM: provisioned")); assert!( lines .iter() .any(|line| line.contains("Product: RNode (0x03)")) ); + assert!(lines.iter().any(|line| line == " Model: 0xb4")); + assert!(lines.iter().any(|line| line == " Radio family: SX1278")); + assert!( + lines + .iter() + .any(|line| line == " Frequency range: 420000000 - 520000000 Hz") + ); + assert!( + lines + .iter() + .any(|line| line == " Maximum TX power: 17 dBm") + ); assert!(lines.iter().any(|line| line.contains("Startup mode: TNC"))); assert!( lines .iter() .any(|line| line.contains("Frequency: 868000000 Hz")) ); + assert!(!lines.iter().any(|line| line.contains("420 - 520 MHz"))); + } + + #[test] + fn eeprom_summary_quarantines_ambiguous_model_capabilities() { + let image = provisioned_eeprom(0x16, None); + let lines = eeprom_summary_lines(&image); + + assert!(lines.iter().any(|line| line == " Model: 0x16")); + assert!( + lines + .iter() + .any(|line| line == " Radio capabilities: unavailable for this model") + ); + assert!(!lines.iter().any(|line| line.contains("Radio family:"))); + assert!(!lines.iter().any(|line| line.contains("Frequency range:"))); + assert!(!lines.iter().any(|line| line.contains("Maximum TX power:"))); + } + + #[test] + fn eeprom_summary_does_not_trust_an_invalid_identity_checksum() { + let image = provisioned_eeprom(0xB4, None); + let mut bytes = image.bytes().to_vec(); + bytes[eeprom::ADDR_CHKSUM] ^= 0x01; + let invalid = eeprom::EepromImage::new(bytes).unwrap(); + let lines = eeprom_summary_lines(&invalid); + + assert!( + lines + .iter() + .any(|line| line == " Product code: 0x03 (unvalidated)") + ); + assert!( + lines + .iter() + .any(|line| line == " Model code: 0xb4 (unvalidated)") + ); + assert!( + lines + .iter() + .any(|line| line == " Identity checksum: invalid") + ); + assert!( + lines + .iter() + .any(|line| line.contains("Radio capabilities: unavailable")) + ); + assert!(lines.iter().any(|line| line == " Serial: 01020304")); + assert!(!lines.iter().any(|line| line.contains("Product: RNode"))); + assert!(!lines.iter().any(|line| line.contains("Radio family:"))); + assert!(!lines.iter().any(|line| line.contains("Frequency range:"))); + assert!(!lines.iter().any(|line| line.contains("Maximum TX power:"))); } #[test] diff --git a/crates/rns-tools/src/commands/rnodeconf/model.rs b/crates/rns-tools/src/commands/rnodeconf/model.rs index 792188e..2b4b189 100644 --- a/crates/rns-tools/src/commands/rnodeconf/model.rs +++ b/crates/rns-tools/src/commands/rnodeconf/model.rs @@ -1,4 +1,8 @@ -//! RNode platform, product and firmware model tables. +//! RNode platform, product and firmware model metadata. +//! +//! Radio families and numeric operating limits belong to +//! `rns_interface::rnode_capabilities`; this tool-local table contains only +//! metadata needed to plan firmware operations. pub const PLATFORM_AVR: u8 = 0x90; pub const PLATFORM_ESP32: u8 = 0x80; @@ -32,439 +36,61 @@ pub const MODEL_B9_TCXO: u8 = 0x09; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ModelInfo { pub model: u8, - pub min_frequency: u32, - pub max_frequency: u32, - pub max_tx_power: u8, - pub band_label: &'static str, pub firmware_filename: Option<&'static str>, - pub radio: &'static str, } pub const MODELS: &[ModelInfo] = &[ - model( - 0xA4, - 410000000, - 525000000, - 14, - "410 - 525 MHz", - Some("rnode_firmware.hex"), - "SX1278", - ), - model( - 0xA9, - 820000000, - 1020000000, - 17, - "820 - 1020 MHz", - Some("rnode_firmware.hex"), - "SX1276", - ), - model( - 0xA1, - 410000000, - 525000000, - 22, - "410 - 525 MHz", - Some("rnode_firmware_t3s3.zip"), - "SX1268", - ), - model( - 0xA6, - 820000000, - 1020000000, - 22, - "820 - 960 MHz", - Some("rnode_firmware_t3s3.zip"), - "SX1262", - ), - model( - 0xA5, - 410000000, - 525000000, - 17, - "410 - 525 MHz", - Some("rnode_firmware_t3s3_sx127x.zip"), - "SX1278", - ), - model( - 0xAA, - 820000000, - 1020000000, - 17, - "820 - 960 MHz", - Some("rnode_firmware_t3s3_sx127x.zip"), - "SX1276", - ), - model( - 0xAC, - 2400000000, - 2500000000, - 20, - "2.4 - 2.5 GHz", - Some("rnode_firmware_t3s3_sx1280_pa.zip"), - "SX1280", - ), - model( - 0xA2, - 410000000, - 525000000, - 17, - "410 - 525 MHz", - Some("rnode_firmware_ng21.zip"), - "SX1278", - ), - model( - 0xA7, - 820000000, - 1020000000, - 17, - "820 - 1020 MHz", - Some("rnode_firmware_ng21.zip"), - "SX1276", - ), - model( - 0xA3, - 410000000, - 525000000, - 17, - "410 - 525 MHz", - Some("rnode_firmware_ng20.zip"), - "SX1278", - ), - model( - 0xA8, - 820000000, - 1020000000, - 17, - "820 - 1020 MHz", - Some("rnode_firmware_ng20.zip"), - "SX1276", - ), - model( - 0xB3, - 420000000, - 520000000, - 17, - "420 - 520 MHz", - Some("rnode_firmware_lora32v20.zip"), - "SX1278", - ), - model( - 0xB8, - 850000000, - 950000000, - 17, - "850 - 950 MHz", - Some("rnode_firmware_lora32v20.zip"), - "SX1276", - ), - model( - 0xB4, - 420000000, - 520000000, - 17, - "420 - 520 MHz", - Some("rnode_firmware_lora32v21.zip"), - "SX1278", - ), - model( - 0xB9, - 850000000, - 950000000, - 17, - "850 - 950 MHz", - Some("rnode_firmware_lora32v21.zip"), - "SX1276", - ), - model( - MODEL_B4_TCXO, - 420000000, - 520000000, - 17, - "420 - 520 MHz", - Some("rnode_firmware_lora32v21_tcxo.zip"), - "SX1278", - ), - model( - MODEL_B9_TCXO, - 850000000, - 950000000, - 17, - "850 - 950 MHz", - Some("rnode_firmware_lora32v21_tcxo.zip"), - "SX1276", - ), - model( - 0xBA, - 420000000, - 520000000, - 17, - "420 - 520 MHz", - Some("rnode_firmware_lora32v10.zip"), - "SX1278", - ), - model( - 0xBB, - 850000000, - 950000000, - 17, - "850 - 950 MHz", - Some("rnode_firmware_lora32v10.zip"), - "SX1276", - ), - model( - 0xC4, - 420000000, - 520000000, - 17, - "420 - 520 MHz", - Some("rnode_firmware_heltec32v2.zip"), - "SX1278", - ), - model( - 0xC9, - 850000000, - 950000000, - 17, - "850 - 950 MHz", - Some("rnode_firmware_heltec32v2.zip"), - "SX1276", - ), - model( - 0xC5, - 420000000, - 520000000, - 22, - "420 - 520 MHz", - Some("rnode_firmware_heltec32v3.zip"), - "SX1268", - ), - model( - 0xCA, - 850000000, - 950000000, - 22, - "850 - 950 MHz", - Some("rnode_firmware_heltec32v3.zip"), - "SX1262", - ), - model( - 0xC8, - 860000000, - 930000000, - 28, - "850 - 950 MHz", - Some("rnode_firmware_heltec32v4pa.zip"), - "SX1262", - ), - model( - 0xC6, - 420000000, - 520000000, - 22, - "420 - 520 MHz", - Some("rnode_firmware_heltec_t114.zip"), - "SX1268", - ), - model( - 0xC7, - 850000000, - 950000000, - 22, - "850 - 950 MHz", - Some("rnode_firmware_heltec_t114.zip"), - "SX1262", - ), - model( - 0xE4, - 420000000, - 520000000, - 17, - "420 - 520 MHz", - Some("rnode_firmware_tbeam.zip"), - "SX1278", - ), - model( - 0xE9, - 850000000, - 950000000, - 17, - "850 - 950 MHz", - Some("rnode_firmware_tbeam.zip"), - "SX1276", - ), - model( - 0xD4, - 420000000, - 520000000, - 22, - "420 - 520 MHz", - Some("rnode_firmware_tdeck.zip"), - "SX1268", - ), - model( - 0xD9, - 850000000, - 950000000, - 22, - "850 - 950 MHz", - Some("rnode_firmware_tdeck.zip"), - "SX1262", - ), - model( - 0xDB, - 420000000, - 520000000, - 22, - "420 - 520 MHz", - Some("rnode_firmware_tbeam_supreme.zip"), - "SX1268", - ), - model( - 0xDC, - 850000000, - 950000000, - 22, - "850 - 950 MHz", - Some("rnode_firmware_tbeam_supreme.zip"), - "SX1262", - ), - model( - 0xE3, - 420000000, - 520000000, - 22, - "420 - 520 MHz", - Some("rnode_firmware_tbeam_sx1262.zip"), - "SX1268", - ), - model( - 0xE8, - 850000000, - 950000000, - 22, - "850 - 950 MHz", - Some("rnode_firmware_tbeam_sx1262.zip"), - "SX1262", - ), - model( - 0x11, - 430000000, - 510000000, - 22, - "430 - 510 MHz", - Some("rnode_firmware_rak4631.zip"), - "SX1262", - ), - model( - 0x12, - 779000000, - 928000000, - 22, - "779 - 928 MHz", - Some("rnode_firmware_rak4631.zip"), - "SX1262", - ), - model( - 0x13, - 430000000, - 510000000, - 22, - "430 - 510 MHz", - Some("rnode_firmware_rak4631_sx1280.zip"), - "SX1262 + SX1280", - ), - model( - 0x14, - 779000000, - 928000000, - 22, - "779 - 928 MHz", - Some("rnode_firmware_rak4631_sx1280.zip"), - "SX1262 + SX1280", - ), - model( - 0x16, - 779000000, - 928000000, - 22, - "430 - 510 Mhz", - Some("rnode_firmware_techo.zip"), - "SX1262", - ), - model( - 0x17, - 779000000, - 928000000, - 22, - "779 - 928 Mhz", - Some("rnode_firmware_techo.zip"), - "SX1262", - ), - model( - 0x21, - 820000000, - 960000000, - 22, - "820 - 960 MHz", - Some("rnode_firmware_opencom_xl.zip"), - "SX1262 + SX1280", - ), - model( - 0xDE, - 420000000, - 520000000, - 22, - "420 - 520 MHz", - Some("rnode_firmware_xiao_esp32s3.zip"), - "SX1262", - ), - model( - 0xDD, - 850000000, - 950000000, - 22, - "850 - 950 MHz", - Some("rnode_firmware_xiao_esp32s3.zip"), - "SX1262", - ), - model( - 0xFE, - 100000000, - 1100000000, - 17, - "(Band capabilities unknown)", - None, - "Unknown", - ), - model( - 0xFF, - 100000000, - 1100000000, - 14, - "(Band capabilities unknown)", - None, - "Unknown", - ), + model(0xA4, Some("rnode_firmware.hex")), + model(0xA9, Some("rnode_firmware.hex")), + model(0xA1, Some("rnode_firmware_t3s3.zip")), + model(0xA6, Some("rnode_firmware_t3s3.zip")), + model(0xA5, Some("rnode_firmware_t3s3_sx127x.zip")), + model(0xAA, Some("rnode_firmware_t3s3_sx127x.zip")), + model(0xAC, Some("rnode_firmware_t3s3_sx1280_pa.zip")), + model(0xA2, Some("rnode_firmware_ng21.zip")), + model(0xA7, Some("rnode_firmware_ng21.zip")), + model(0xA3, Some("rnode_firmware_ng20.zip")), + model(0xA8, Some("rnode_firmware_ng20.zip")), + model(0xB3, Some("rnode_firmware_lora32v20.zip")), + model(0xB8, Some("rnode_firmware_lora32v20.zip")), + model(0xB4, Some("rnode_firmware_lora32v21.zip")), + model(0xB9, Some("rnode_firmware_lora32v21.zip")), + model(MODEL_B4_TCXO, Some("rnode_firmware_lora32v21_tcxo.zip")), + model(MODEL_B9_TCXO, Some("rnode_firmware_lora32v21_tcxo.zip")), + model(0xBA, Some("rnode_firmware_lora32v10.zip")), + model(0xBB, Some("rnode_firmware_lora32v10.zip")), + model(0xC4, Some("rnode_firmware_heltec32v2.zip")), + model(0xC9, Some("rnode_firmware_heltec32v2.zip")), + model(0xC5, Some("rnode_firmware_heltec32v3.zip")), + model(0xCA, Some("rnode_firmware_heltec32v3.zip")), + model(0xC8, Some("rnode_firmware_heltec32v4pa.zip")), + model(0xC6, Some("rnode_firmware_heltec_t114.zip")), + model(0xC7, Some("rnode_firmware_heltec_t114.zip")), + model(0xE4, Some("rnode_firmware_tbeam.zip")), + model(0xE9, Some("rnode_firmware_tbeam.zip")), + model(0xD4, Some("rnode_firmware_tdeck.zip")), + model(0xD9, Some("rnode_firmware_tdeck.zip")), + model(0xDB, Some("rnode_firmware_tbeam_supreme.zip")), + model(0xDC, Some("rnode_firmware_tbeam_supreme.zip")), + model(0xE3, Some("rnode_firmware_tbeam_sx1262.zip")), + model(0xE8, Some("rnode_firmware_tbeam_sx1262.zip")), + model(0x11, Some("rnode_firmware_rak4631.zip")), + model(0x12, Some("rnode_firmware_rak4631.zip")), + model(0x13, Some("rnode_firmware_rak4631_sx1280.zip")), + model(0x14, Some("rnode_firmware_rak4631_sx1280.zip")), + model(0x16, Some("rnode_firmware_techo.zip")), + model(0x17, Some("rnode_firmware_techo.zip")), + model(0x21, Some("rnode_firmware_opencom_xl.zip")), + model(0xDE, Some("rnode_firmware_xiao_esp32s3.zip")), + model(0xDD, Some("rnode_firmware_xiao_esp32s3.zip")), + model(0xFE, None), + model(0xFF, None), ]; -const fn model( - model: u8, - min_frequency: u32, - max_frequency: u32, - max_tx_power: u8, - band_label: &'static str, - firmware_filename: Option<&'static str>, - radio: &'static str, -) -> ModelInfo { +const fn model(model: u8, firmware_filename: Option<&'static str>) -> ModelInfo { ModelInfo { model, - min_frequency, - max_frequency, - max_tx_power, - band_label, firmware_filename, - radio, } } @@ -480,28 +106,6 @@ pub fn normalize_eeprom_model(model: u8) -> u8 { } } -pub fn product_name(product: u8) -> Option<&'static str> { - Some(match product { - PRODUCT_RNODE => "RNode", - PRODUCT_HMBRW => "Hombrew RNode", - PRODUCT_TBEAM => "LilyGO T-Beam", - PRODUCT_TBEAM_S_V1 => "LilyGO T-Beam Supreme", - PRODUCT_TDECK => "LilyGO T-Deck", - PRODUCT_T32_10 => "LilyGO LoRa32 v1.0", - PRODUCT_T32_20 => "LilyGO LoRa32 v2.0", - PRODUCT_T32_21 => "LilyGO LoRa32 v2.1", - PRODUCT_H32_V2 => "Heltec LoRa32 v2", - PRODUCT_H32_V3 => "Heltec LoRa32 v3", - PRODUCT_H32_V4 => "Heltec LoRa32 v4", - PRODUCT_TECHO => "LilyGO T-Echo", - PRODUCT_RAK4631 => "RAK4631", - PRODUCT_OPENCOM_XL => "openCom XL", - PRODUCT_HELTEC_T114 => "Heltec Mesh Node T114", - PRODUCT_XIAO_S3 => "Seeed XIAO ESP32S3 Wio-SX1262", - _ => return None, - }) -} - pub fn platform_name(platform: u8) -> Option<&'static str> { Some(match platform { PLATFORM_AVR => "AVR", @@ -526,7 +130,7 @@ mod tests { use super::*; #[test] - fn model_table_matches_upstream_shape() { + fn model_table_retains_only_firmware_planning_metadata() { assert_eq!(MODELS.len(), 45); assert_eq!( model_info(0xA4).unwrap().firmware_filename, @@ -537,7 +141,7 @@ mod tests { Some("rnode_firmware_t3s3_sx1280_pa.zip") ); assert_eq!(model_info(0xFE).unwrap().firmware_filename, None); - assert_eq!(model_info(0xFF).unwrap().max_tx_power, 14); + assert_eq!(model_info(0xFF).unwrap().firmware_filename, None); } #[test] @@ -548,8 +152,7 @@ mod tests { } #[test] - fn names_match_upstream_spellings() { - assert_eq!(product_name(PRODUCT_HMBRW), Some("Hombrew RNode")); + fn platform_and_mcu_names_match_upstream_spellings() { assert_eq!(platform_name(PLATFORM_ESP32), Some("ESP32")); assert_eq!(mcu_name(MCU_NRF52), Some("Nordic Semiconductor nRF52840")); }