use crate::{Error, Result};
use ::freefare_sys;
pub struct Mad {
inner: freefare_sys::Mad,
}
impl Mad {
pub fn new(version: u8) -> Result<Self> {
let raw_mad = unsafe { freefare_sys::mad_new(version) };
if raw_mad.is_null() {
Err(Error::new(format!(
"Failed to create Mad instance for version: {}",
version
)))
} else {
Ok(Self { inner: raw_mad })
}
}
pub fn read(tag: freefare_sys::FreefareTag) -> Result<Self> {
if tag.is_null() {
return Err(Error::new("Tag is null. Cannot read MAD."));
}
let raw_mad = unsafe { freefare_sys::mad_read(tag) };
if raw_mad.is_null() {
Err(Error::new("Failed to read MAD from the tag."))
} else {
Ok(Self { inner: raw_mad })
}
}
pub fn write(
&self,
tag: freefare_sys::FreefareTag,
key_b_sector_00: *const freefare_sys::MifareClassicKey,
key_b_sector_10: *const freefare_sys::MifareClassicKey,
) -> Result<()> {
if tag.is_null() {
return Err(Error::new("Tag is null. Cannot write MAD."));
}
let result =
unsafe { freefare_sys::mad_write(tag, self.inner, key_b_sector_00, key_b_sector_10) };
if result < 0 {
Err(Error::new(format!(
"Failed to write MAD to the tag. Error code: {}",
result
)))
} else {
Ok(())
}
}
pub fn get_version(&self) -> Result<i32> {
let result = unsafe { freefare_sys::mad_get_version(self.inner) };
if result < 0 {
Err(Error::new(format!(
"Failed to get MAD version. Error code: {}",
result
)))
} else {
Ok(result)
}
}
pub fn set_version(&mut self, version: u8) -> Result<()> {
unsafe { freefare_sys::mad_set_version(self.inner, version) };
Ok(())
}
pub fn get_card_publisher_sector(&self) -> Result<freefare_sys::MifareClassicSectorNumber> {
let result = unsafe { freefare_sys::mad_get_card_publisher_sector(self.inner) };
Ok(result)
}
pub fn set_card_publisher_sector(
&mut self,
cps: freefare_sys::MifareClassicSectorNumber,
) -> Result<()> {
let result = unsafe { freefare_sys::mad_set_card_publisher_sector(self.inner, cps) };
if result < 0 {
Err(Error::new(format!(
"Failed to set card publisher sector. Error code: {}",
result
)))
} else {
Ok(())
}
}
pub fn get_aid(
&self,
sector: freefare_sys::MifareClassicSectorNumber,
aid: &mut freefare_sys::MadAid,
) -> Result<()> {
let result = unsafe { freefare_sys::mad_get_aid(self.inner, sector, aid) };
if result < 0 {
Err(Error::new(format!(
"Failed to get AID. Error code: {}",
result
)))
} else {
Ok(())
}
}
pub fn set_aid(
&mut self,
sector: freefare_sys::MifareClassicSectorNumber,
aid: freefare_sys::MadAid,
) -> Result<()> {
let result = unsafe { freefare_sys::mad_set_aid(self.inner, sector, aid) };
if result < 0 {
Err(Error::new(format!(
"Failed to set AID. Error code: {}",
result
)))
} else {
Ok(())
}
}
pub fn sector_reserved(sector: freefare_sys::MifareClassicSectorNumber) -> bool {
unsafe { freefare_sys::mad_sector_reserved(sector) }
}
}
impl Drop for Mad {
fn drop(&mut self) {
unsafe {
freefare_sys::mad_free(self.inner);
}
}
}