96 lines
2.6 KiB
Rust
96 lines
2.6 KiB
Rust
use core::fmt::Display;
|
|
|
|
use crate::card::model::NfcPayload;
|
|
use alloc::string::{String, ToString};
|
|
|
|
pub fn split_nfc_hex(payload: &[u8]) -> Option<NfcPayload> {
|
|
if payload.len() < 0x35A {
|
|
return None;
|
|
}
|
|
|
|
Some(NfcPayload {
|
|
event_encoding: payload[0..2].try_into().ok()?,
|
|
card_type: payload[2],
|
|
card_uuid: payload[3..5].try_into().ok()?,
|
|
_reserved: payload[5..9].try_into().ok()?,
|
|
sprite: payload[9..0x2DB].try_into().ok()?,
|
|
packed_card_text: payload[0x2DB..0x311].try_into().ok()?,
|
|
secret: payload[0x311..0x329].try_into().ok()?,
|
|
_opaque_trailer: payload[0x329..0x35A].try_into().ok()?,
|
|
})
|
|
}
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub enum Events {
|
|
CCC39,
|
|
CCC40,
|
|
GPN24,
|
|
GPN25,
|
|
Unknown,
|
|
}
|
|
|
|
impl Display for Events {
|
|
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
|
match *self {
|
|
Events::CCC39 => write!(f, "39C3"),
|
|
Events::CCC40 => write!(f, "40C3"),
|
|
Events::GPN24 => write!(f, "GPN24"),
|
|
Events::GPN25 => write!(f, "GPN25"),
|
|
Events::Unknown => write!(f, "Unknown"),
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn decode_known_event(event_encoding: &[u8]) -> Events {
|
|
match event_encoding {
|
|
[0x39, 0xC3] => Events::CCC39,
|
|
[0x40, 0xC3] => Events::CCC40, // future proofing :)
|
|
[0xE9, 0x24] => Events::GPN24,
|
|
[0xE9, 0x25] => Events::GPN25, // future proofing :)
|
|
_ => Events::Unknown,
|
|
}
|
|
}
|
|
|
|
pub fn decode_secret(hex: &[u8]) -> String {
|
|
let mut ascii_string = String::new();
|
|
for &byte in hex {
|
|
if byte == 0 {
|
|
break;
|
|
}
|
|
|
|
if byte.is_ascii_graphic() || byte == b' ' {
|
|
ascii_string.push(byte as char);
|
|
}
|
|
}
|
|
ascii_string
|
|
}
|
|
|
|
pub fn decode_packed_card_text(bytes: &[u8]) -> (String, String, String, String) {
|
|
let alphabet = b" ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-";
|
|
let mut full_text = String::with_capacity((bytes.len() * 8) / 6 + 1);
|
|
|
|
let mut accumulator: u32 = 0;
|
|
let mut bits_in_acc: u32 = 0;
|
|
|
|
for &byte in bytes {
|
|
accumulator |= (byte as u32) << bits_in_acc;
|
|
bits_in_acc += 8;
|
|
|
|
while bits_in_acc >= 6 {
|
|
let char_index = (accumulator & 0x3F) as usize;
|
|
|
|
full_text.push(alphabet[char_index] as char);
|
|
|
|
accumulator >>= 6;
|
|
bits_in_acc -= 6;
|
|
}
|
|
}
|
|
|
|
let name = full_text[0..24].trim().to_string();
|
|
let trait1 = full_text[24..40].trim().to_string();
|
|
let trait2 = full_text[40..56].trim().to_string();
|
|
let trait3 = full_text[56..72].trim().to_string();
|
|
|
|
(name, trait1, trait2, trait3)
|
|
}
|