diff --git a/Cargo.lock b/Cargo.lock index 80f74f0..76962d9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -657,6 +657,9 @@ name = "hex" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +dependencies = [ + "serde", +] [[package]] name = "hound" diff --git a/Cargo.toml b/Cargo.toml index 30a5e8a..f6ddce4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,7 +29,7 @@ tokio-io-timeout = "1.2.0" thiserror = "1.0.37" futures-util = "0.3.24" glob = "0.3.0" -hex = "0.4.3" +hex = { version = "0.4.3", features = ["serde"] } linux-embedded-hal = "0.3.2" embedded-hal = "0.2.7" rodio = { version = "0.17.1", features = ["symphonia-mp3"] } diff --git a/src/nfc/reader.rs b/src/nfc/reader.rs index 4db3e3b..34aff13 100644 --- a/src/nfc/reader.rs +++ b/src/nfc/reader.rs @@ -1,10 +1,47 @@ use anyhow::{anyhow, Result}; +use hex::{decode_to_slice, encode, FromHex, FromHexError}; use mfrc522::comm::Interface; use mfrc522::{Initialized, Mfrc522}; +use serde::{Deserialize, Deserializer, Serialize, Serializer}; use crate::nfc::ndef::{parse_ndef_text_record, NdefMessageParser}; -pub type Uid = [u8; 7]; +#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +pub struct NfcUid([u8; 7]); + +impl NfcUid { + pub fn as_bytes(&self) -> &[u8; 7] { + &self.0 + } +} + +impl<'de> Deserialize<'de> for NfcUid { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + Ok(Self(hex::deserialize(deserializer)?)) + } +} + +impl Serialize for NfcUid { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + Ok(serializer.serialize_str(&encode(&self.0))?) + } +} + +impl FromHex for NfcUid { + type Error = FromHexError; + + fn from_hex>(hex: T) -> Result { + let mut out = Self([0; 7]); + decode_to_slice(hex, &mut out.0 as &mut [u8])?; + Ok(out) + } +} pub struct NfcReader { mfrc522: Mfrc522, @@ -15,7 +52,7 @@ impl> NfcReader { Self { mfrc522 } } - pub fn select_target(&mut self) -> Option { + pub fn select_target(&mut self) -> Option { let atqa = match self.mfrc522.reqa() { Ok(atqa) => atqa, Err(_) => return None, @@ -26,7 +63,7 @@ impl> NfcReader { Err(_) => return None, }; - let mut uid: Uid = [0; 7]; + let mut uid: [u8; 7] = [0; 7]; match raw_uid { mfrc522::Uid::Single(raw_uid) => uid[0..4].copy_from_slice(raw_uid.as_bytes()), @@ -34,7 +71,7 @@ impl> NfcReader { mfrc522::Uid::Triple(raw_uid) => uid.copy_from_slice(&raw_uid.as_bytes()[0..7]), } - Some(uid) + Some(NfcUid(uid)) } pub fn check_for_release(&mut self) -> bool { diff --git a/src/nfc/thread.rs b/src/nfc/thread.rs index 1402fe5..1ff4ded 100644 --- a/src/nfc/thread.rs +++ b/src/nfc/thread.rs @@ -13,12 +13,12 @@ use tokio::sync::mpsc; use tokio::sync::oneshot; use tokio::sync::oneshot::error::TryRecvError; -use crate::nfc::reader::{NfcReader, Uid}; +use crate::nfc::reader::{NfcReader, NfcUid}; #[derive(Debug)] pub enum NfcCommand { Poll { - responder: oneshot::Sender, + responder: oneshot::Sender, cancel_rx: oneshot::Receiver<()>, }, Read { diff --git a/src/subsystems/config_manager.rs b/src/subsystems/config_manager.rs index 90766c3..f88d56f 100644 --- a/src/subsystems/config_manager.rs +++ b/src/subsystems/config_manager.rs @@ -1,6 +1,6 @@ use std::path::{Path, PathBuf}; -use crate::nfc::reader::Uid; +use crate::nfc::reader::NfcUid; use anyhow::{Error, Result}; use log::info; use serde::{Deserialize, Serialize}; @@ -26,7 +26,7 @@ pub struct VolumeConfig { #[derive(Clone, Deserialize, Serialize)] pub struct Config { - pub config_uids: Vec, + pub config_uids: Vec, pub connection: Option, pub volume: VolumeConfig, } @@ -34,10 +34,10 @@ pub struct Config { #[derive(Debug)] pub enum ConfigCommand { GetConfigUids { - responder: oneshot::Sender>, + responder: oneshot::Sender>, }, SetConfigUids { - config_uids: Vec, + config_uids: Vec, responder: oneshot::Sender<()>, }, GetVolume { @@ -131,7 +131,7 @@ impl ConfigManager { } async fn store_config(&self, config: &Config) -> Result<()> { - let toml_config = toml::to_string(&config)?; + let toml_config = toml::to_string_pretty(&config)?; let mut file = File::create(&self.config_path).await?; file.write_all(toml_config.as_bytes()).await?; Ok(()) diff --git a/src/subsystems/controller.rs b/src/subsystems/controller.rs index 7a1b912..9027bed 100644 --- a/src/subsystems/controller.rs +++ b/src/subsystems/controller.rs @@ -12,7 +12,7 @@ use tokio::sync::oneshot; use tokio::time::sleep; use tokio_graceful_shutdown::{IntoSubsystem, SubsystemHandle}; -use crate::nfc::reader::Uid; +use crate::nfc::reader::NfcUid; use crate::nfc::thread::{start_nfc_listener, NfcCommand}; use crate::subsystems::audio_player::PlayerCommand; use crate::subsystems::config_manager::{ConfigCommand, ConnectionConfig}; @@ -203,8 +203,8 @@ impl Controller { async fn process_config_command( &mut self, - uid: Uid, - config_uids: &mut Vec, + uid: NfcUid, + config_uids: &mut Vec, nfc: mpsc::Sender, ) -> Result { let (value_tx, value_rx) = oneshot::channel(); @@ -302,7 +302,7 @@ impl Controller { async fn add_config_uid( &mut self, - config_uids: &mut Vec, + config_uids: &mut Vec, nfc: mpsc::Sender, ) -> Result<()> { self.led.send(LedState::Blink { color: MAGENTA }).await?; diff --git a/src/subsystems/networker.rs b/src/subsystems/networker.rs index 0335493..4fcaf56 100644 --- a/src/subsystems/networker.rs +++ b/src/subsystems/networker.rs @@ -23,7 +23,7 @@ use tokio_rustls::client::TlsStream; use tokio_rustls::rustls::{self, ClientConfig, OwnedTrustAnchor}; use tokio_rustls::TlsConnector; -use crate::nfc::reader::Uid; +use crate::nfc::reader::NfcUid; use crate::subsystems::config_manager::{ConfigCommand, ConnectionConfig}; use crate::utils::skip_certificate_verification::SkipCertificateVerification; @@ -56,7 +56,7 @@ pub enum NetworkerCommand { connection_config: ConnectionConfig, }, CheckUid { - uid: Uid, + uid: NfcUid, responder: oneshot::Sender, }, GetAudio { @@ -235,11 +235,11 @@ impl Networker { TlsConnector::from(Arc::new(client_config)) } - async fn check_uid(&mut self, uid: &Uid) -> Result { + async fn check_uid(&mut self, uid: &NfcUid) -> Result { let stream = self.maybe_stream.as_mut().unwrap(); stream.write_u8(0x00).await?; - stream.write_all(uid).await?; + stream.write_all(uid.as_bytes()).await?; let result = stream.read_u8().await?;