hardware 0.0.9

A no_std bare-metal hardware abstraction layer — all port I/O, memory and swap allocations are guarded at runtime. Do not consider this dependency stable before x.1.x
Documentation
pub const NDEF_MAGIC: u8 = 0xE1;
pub const NDEF_TLV_TERMINATOR: u8 = 0xFE;
pub const NDEF_TLV_NDEF_MESSAGE: u8 = 0x03;
pub const NDEF_TLV_NULL: u8 = 0x00;

pub const MAX_UID_LEN: usize = 10;
pub const MAX_NDEF_SIZE: usize = 256;

#[derive(Clone, Copy, PartialEq)]
pub enum NdefRecordType {
    Text,
    Uri,
    SmartPoster,
    MimeMedia,
    AbsoluteUri,
    External,
    Unknown,
}

#[derive(Clone, Copy)]
pub struct TagUid {
    pub bytes: [u8; MAX_UID_LEN],
    pub len: u8,
}

impl TagUid {
    pub const fn empty() -> Self {
        TagUid {
            bytes: [0u8; MAX_UID_LEN],
            len: 0,
        }
    }

    pub fn uid_bytes(&self) -> &[u8] {
        &self.bytes[..self.len as usize]
    }

    pub fn is_valid(&self) -> bool {
        self.len > 0 && self.len as usize <= MAX_UID_LEN
    }
}

pub struct NdefMessage {
    pub data: [u8; MAX_NDEF_SIZE],
    pub len: usize,
}

impl NdefMessage {
    pub const fn empty() -> Self {
        NdefMessage {
            data: [0u8; MAX_NDEF_SIZE],
            len: 0,
        }
    }

    pub fn bytes(&self) -> &[u8] {
        &self.data[..self.len]
    }
}

pub fn has_ndef_magic(data: &[u8]) -> bool {
    !data.is_empty() && data[0] == NDEF_MAGIC
}

pub fn find_ndef_tlv(data: &[u8]) -> Option<(usize, usize)> {
    let mut i = 0;
    while i < data.len() {
        let tag = data[i];
        if tag == NDEF_TLV_TERMINATOR {
            return None;
        }
        if tag == NDEF_TLV_NULL {
            i += 1;
            continue;
        }
        if i + 1 >= data.len() {
            return None;
        }
        let length = data[i + 1] as usize;
        if tag == NDEF_TLV_NDEF_MESSAGE {
            let start = i + 2;
            if start + length <= data.len() {
                return Some((start, length));
            }
            return None;
        }
        i += 2 + length;
    }
    None
}

pub fn ndef_record_tnf(header: u8) -> u8 {
    header & 0x07
}

pub fn ndef_record_type_from_tnf(tnf: u8) -> NdefRecordType {
    match tnf {
        0x01 => NdefRecordType::Text,
        0x02 => NdefRecordType::MimeMedia,
        0x03 => NdefRecordType::AbsoluteUri,
        0x04 => NdefRecordType::External,
        _ => NdefRecordType::Unknown,
    }
}

pub fn is_uri_record(type_field: &[u8]) -> bool {
    type_field.len() == 1 && type_field[0] == b'U'
}

pub fn is_text_record(type_field: &[u8]) -> bool {
    type_field.len() == 1 && type_field[0] == b'T'
}