From ce5183da38b76d87615791066a587710eca2f665 Mon Sep 17 00:00:00 2001 From: rhetenor Date: Tue, 25 Aug 2026 19:33:27 +0000 Subject: [PATCH] storage: implement get card by uuid --- src/card/decoder.rs | 16 +++++++-------- src/card/model.rs | 31 ++++++++++++++++------------- src/storage/cardstore.rs | 43 +++++++++++++++++++++++++++++++--------- 3 files changed, 59 insertions(+), 31 deletions(-) diff --git a/src/card/decoder.rs b/src/card/decoder.rs index 60f2a39..0d2f401 100644 --- a/src/card/decoder.rs +++ b/src/card/decoder.rs @@ -3,20 +3,20 @@ use core::fmt::Display; use crate::card::model::NfcPayload; use alloc::string::{String, ToString}; -pub fn split_nfc_hex(payload: &[u8]) -> Option> { +pub fn split_nfc_hex(payload: &[u8]) -> Option { if payload.len() < 0x35A { return None; } Some(NfcPayload { - event_encoding: &payload[0..2], + event_encoding: payload[0..2].try_into().ok()?, card_type: payload[2], - card_uuid: &payload[3..5], - _reserved: &payload[5..9], - sprite: &payload[9..0x2DB], - packed_card_text: &payload[0x2DB..0x311], - secret: &payload[0x311..0x329], - _opaque_trailer: &payload[0x329..0x35A], + 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()?, }) } diff --git a/src/card/model.rs b/src/card/model.rs index 5747671..6374e64 100644 --- a/src/card/model.rs +++ b/src/card/model.rs @@ -6,16 +6,19 @@ use num_enum::FromPrimitive; use crate::card::decoder::{Events, decode_known_event, decode_packed_card_text, decode_secret}; use embedded_graphics::pixelcolor::{Rgb565, Rgb888}; -#[derive(Debug, Clone, Copy)] -pub struct NfcPayload<'a> { - pub event_encoding: &'a [u8], +use binary_serde::BinarySerde; + +#[derive(Debug, BinarySerde, PartialEq, Eq, Clone, Copy)] +#[repr(C)] +pub struct NfcPayload { + pub event_encoding: [u8; 2], pub card_type: u8, - pub card_uuid: &'a [u8], - pub _reserved: &'a [u8], - pub sprite: &'a [u8], - pub packed_card_text: &'a [u8], - pub secret: &'a [u8], - pub _opaque_trailer: &'a [u8], + pub card_uuid: [u8; 2], + pub _reserved: [u8; 4], + pub sprite: [u8; 722], + pub packed_card_text: [u8; 54], + pub secret: [u8; 24], + pub _opaque_trailer: [u8; 49], } #[derive(Debug, Clone, Eq, PartialEq, FromPrimitive)] @@ -235,15 +238,15 @@ pub struct Card { pub sprite: Sprite, } -impl<'a> TryFrom> for Card { +impl<'a> TryFrom for Card { type Error = &'static str; - fn try_from(payload: NfcPayload<'a>) -> Result { + fn try_from(payload: NfcPayload) -> Result { let uuid: String = "empty for now".into(); //str::from_utf8(payload.card_uuid).unwrap().into(); - let event = decode_known_event(payload.event_encoding); + let event = decode_known_event(&payload.event_encoding); let cardtype = CardType::from(payload.card_type); - let (name, trait1, trait2, trait3) = decode_packed_card_text(payload.packed_card_text); - let secret = decode_secret(payload.secret); + let (name, trait1, trait2, trait3) = decode_packed_card_text(&payload.packed_card_text); + let secret = decode_secret(&payload.secret); let sprite = Sprite { data: payload.sprite.to_vec(), }; diff --git a/src/storage/cardstore.rs b/src/storage/cardstore.rs index 1bd5780..8996d2b 100644 --- a/src/storage/cardstore.rs +++ b/src/storage/cardstore.rs @@ -1,10 +1,11 @@ -use alloc::collections::BTreeMap; use embedded_storage::nor_flash::ReadNorFlash; +use alloc::collections::BTreeMap; use alloc::vec::Vec; -use binary_serde::{BinarySerde, Endianness}; +use binary_serde::{BinarySerde, Endianness, DeserializeError}; //use crate::card::model::NfcPayload; +use crate::card::model::NfcPayload; use crate::storage::store::{Store, StoreError}; use crate::storage::{MemoryRegion,CARDSTORE_REGION}; @@ -15,7 +16,7 @@ const COUNT_REGION: MemoryRegion = MemoryRegion { offset: CARDSTORE_REGION.offse #[derive(Debug, BinarySerde, Default, PartialEq, Eq)] #[repr(C)] -struct AllocationTableEntry { +pub struct AllocationTableEntry { uuid: u32, offset: u32, @@ -36,14 +37,33 @@ const ALLOCATION_TABLE_REGION: MemoryRegion = MemoryRegion {offset: COUNT_REGION const CARDS_REGION: MemoryRegion = MemoryRegion { offset: ALLOCATION_TABLE_REGION.end() as u32, size: CARDSTORE_REGION.size - ALLOCATION_TABLE_REGION.end()}; +#[derive(Debug)] +pub enum CardStoreError { + Store(StoreError), + CorruptedEntry(DeserializeError), + NoEntry +} + +impl From for CardStoreError { + fn from(error: StoreError) -> CardStoreError { + CardStoreError::Store(error) + } +} + +impl From for CardStoreError { + fn from(error: DeserializeError) -> CardStoreError { + CardStoreError::CorruptedEntry(error) + } +} + pub struct CardStore { store: Store, count: usize, - allocation_table: BTreeMap + pub allocation_table: BTreeMap } impl CardStore { - pub fn new(mut store: Store) -> Result { + pub fn new(mut store: Store) -> Result { let mut count_bytes: [u8; COUNT_REGION.size] = [0; COUNT_REGION.size]; store.read(COUNT_REGION.offset, &mut count_bytes)?; @@ -59,15 +79,20 @@ impl CardStore { let mut allocation_table = BTreeMap::::new(); for chunk in chunks { - let allocation_table_entry = AllocationTableEntry::binary_deserialize(chunk.as_ref(), Endianness::Little).unwrap(); + let allocation_table_entry = AllocationTableEntry::binary_deserialize(chunk.as_ref(), Endianness::Little)?; allocation_table.insert(allocation_table_entry.uuid, allocation_table_entry); } Ok(Self { store, count, allocation_table }) } - //fn get_card_by_uuid(uuid: &str) {} + pub fn get_card_by_uuid(&mut self, uuid: u32) -> Result { + let entry = self.allocation_table.get(&uuid).ok_or(CardStoreError::NoEntry)?; + + let mut payload: [u8; size_of::()] = [0; size_of::()]; + self.store.read(entry.offset, &mut payload)?; + + Ok(NfcPayload::binary_deserialize(payload.as_ref(), Endianness::Little)?) + } - //fn get_card_by_position(position: usize) {} - }