use super::{DeviceEntityFirmwareInfo, DeviceEntityType};
fn fw_info(kind: u8) -> [u8; 16] {
let mut payload = [0; 16];
payload[0] = kind;
payload[1..4].copy_from_slice(b"MPM");
payload[4] = 0x17; payload[5] = 0x00; payload[6..8].copy_from_slice(&[0x00, 0x08]); payload[8] = 1; payload[9..11].copy_from_slice(&0xc08du16.to_be_bytes());
payload
}
#[test]
fn decodes_named_entity_types() {
for (byte, kind) in [
(0, DeviceEntityType::MainApplication),
(1, DeviceEntityType::Bootloader),
(2, DeviceEntityType::Hardware),
(9, DeviceEntityType::MotorDrive),
] {
let info = DeviceEntityFirmwareInfo::from_payload(&fw_info(byte)).unwrap();
assert_eq!(info.entity_type, kind);
assert_eq!(u8::from(kind), byte);
}
}
#[test]
fn an_unnamed_entity_type_still_decodes() {
for byte in [10, 15, 0x80] {
let info = DeviceEntityFirmwareInfo::from_payload(&fw_info(byte)).unwrap();
assert_eq!(info.entity_type, DeviceEntityType::Other(byte));
assert_eq!(u8::from(info.entity_type), byte);
assert_eq!(info.firmware_prefix, "MPM");
assert_eq!(
(info.firmware_number, info.revision, info.build),
(17, 0, 8)
);
assert!(info.active);
assert_eq!(info.transport_pid, 0xc08d);
}
}
fn version_and_build(version: [u8; 2], build: [u8; 2]) -> (u8, u8, u16) {
let mut payload = fw_info(0);
payload[4..6].copy_from_slice(&version);
payload[6..8].copy_from_slice(&build);
let info = DeviceEntityFirmwareInfo::from_payload(&payload).unwrap();
(info.firmware_number, info.revision, info.build)
}
#[test]
fn a_bcd_version_decodes_digit_by_digit() {
assert_eq!(version_and_build([0x92, 0x00], [0x00, 0x08]), (92, 0, 8));
assert_eq!(
version_and_build([0x99, 0x99], [0x99, 0x99]),
(99, 99, 9999)
);
}
#[test]
fn a_binary_build_is_read_as_a_number() {
let mut payload = [0; 16];
payload[..8].copy_from_slice(&[0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa9]);
let info = DeviceEntityFirmwareInfo::from_payload(&payload).unwrap();
assert_eq!(info.entity_type, DeviceEntityType::Softdevice);
assert_eq!(info.firmware_prefix, "\0\0\0");
assert_eq!(
(info.firmware_number, info.revision, info.build),
(0, 0, 169)
);
assert!(!info.active);
}
#[test]
fn a_binary_version_is_split_into_two_digit_halves() {
assert_eq!(version_and_build([0x01, 0x0a], [0x00, 0x08]), (2, 66, 8));
assert_eq!(version_and_build([0x17, 0x0a], [0x00, 0x08]), (58, 98, 8));
}
#[test]
fn a_binary_field_is_capped_at_four_digits() {
assert_eq!(
version_and_build([0xff, 0xff], [0xff, 0xff]),
(99, 99, 9999)
);
assert_eq!(version_and_build([0x00, 0x00], [0x26, 0xff]).2, 9983);
assert_eq!(version_and_build([0x00, 0x00], [0x27, 0x0f]).2, 9999);
assert_eq!(version_and_build([0x00, 0x00], [0x27, 0x1a]).2, 9999);
}
#[test]
fn a_prefix_that_is_not_utf8_is_still_refused() {
let mut payload = fw_info(0);
payload[1..4].copy_from_slice(&[0xff, 0xfe, 0xfd]);
DeviceEntityFirmwareInfo::from_payload(&payload).unwrap_err();
}