use crate::{Error, Result, Tag};
use ::freefare_sys;
pub struct Mad {
inner: freefare_sys::Mad,
}
impl Mad {
pub(crate) fn as_ptr(&self) -> freefare_sys::Mad {
self.inner
}
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: &Tag<'_>) -> Result<Self> {
let raw_mad = unsafe { freefare_sys::mad_read(tag.as_ptr()) };
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: &Tag<'_>,
key_b_sector_00: &freefare_sys::MifareClassicKey,
key_b_sector_10: &freefare_sys::MifareClassicKey,
) -> Result<()> {
let result = unsafe {
freefare_sys::mad_write(
tag.as_ptr(),
self.inner,
key_b_sector_00 as *const _,
key_b_sector_10 as *const _,
)
};
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);
}
}
}