ti154 0.3.0

Library for creating and parsing TI 15.4 UART packets.
Documentation
pub mod error;
pub mod frame;
pub mod parser;
pub mod subsystem;
pub mod types;

#[cfg(test)]
mod tests {
    use crate::{frame, subsystem, types};
    use std::io::Cursor;

    #[test]
    fn decode_mt_header_1() {
        let data = [0x00, 0x01, 0x02];
        let mut cursor = Cursor::new(&data[..]);
        let header = frame::MTHeader::try_decode(&mut cursor).unwrap();
        assert_eq!(header.length, 0);
        assert_eq!(header.has_extension(), false);
        assert_eq!(header.command.cmd_type, types::CommandType::POLL);
        assert_eq!(header.command.subsystem, types::MTSubsystem::SYS);
        assert_eq!(header.command.id, 2);
    }

    #[test]
    fn decode_mt_header_2() {
        let data = [0xFF, 0x81, 0x0A];
        let mut cursor = Cursor::new(&data[..]);
        let header = frame::MTHeader::try_decode(&mut cursor).unwrap();
        assert_eq!(header.length, 255);
        assert_eq!(header.has_extension(), true);
        assert_eq!(header.command.cmd_type, types::CommandType::POLL);
        assert_eq!(header.command.subsystem, types::MTSubsystem::SYS);
        assert_eq!(header.command.id, 10);
    }

    #[test]
    fn decode_sys_reset_ind() {
        let data = [0x6, 0x41, 0x80, 0x0, 0x3, 0x1, 0x2, 0x2, 0x0];
        let mut cursor = Cursor::new(&data[..]);
        let frame = frame::MTFrame::try_decode(&mut cursor).unwrap();
        assert_eq!(frame.header.length, 0x06);
        assert_eq!(frame.header.has_extension(), false);
        assert_eq!(frame.header.command.cmd_type, types::CommandType::AREQ);
        assert_eq!(frame.header.command.subsystem, types::MTSubsystem::SYS);
        assert_eq!(frame.header.command.id, types::SYSCommandId::ResetInd as u8);
        assert!(frame.extended_header.is_none());

        if let Ok(payload) = subsystem::sys::areq::ResetInd::try_decode(frame.payload.as_slice()) {
            assert_eq!(payload.reason, types::ResetReason::Hardware);
            assert_eq!(
                payload.transport,
                types::TransportProtocolRevision::ExtendedRPCFrame
            );
            assert_eq!(payload.product, types::ProductIdCode::TI154Stack);
            assert_eq!(payload.major, 0x02);
            assert_eq!(payload.minor, 0x02);
            assert_eq!(payload.maint, 0x00);
        } else {
            panic!("Invalid payload.");
        }
    }

    #[test]
    fn decode_mac_reset_req_srsp() {
        let data = [0x1, 0x62, 0x1, 0x0];
        let mut cursor = Cursor::new(&data[..]);
        let frame = frame::MTFrame::try_decode(&mut cursor).unwrap();
        assert_eq!(frame.header.length, 0x01);
        assert_eq!(frame.header.has_extension(), false);
        assert_eq!(frame.header.command.cmd_type, types::CommandType::SRSP);
        assert_eq!(frame.header.command.subsystem, types::MTSubsystem::MAC);
        assert_eq!(frame.header.command.id, types::MACCommandId::ResetReq as u8);
        assert!(frame.extended_header.is_none());

        if let Ok(payload) = subsystem::mac::srsp::ResetReq::try_decode(frame.payload.as_slice()) {
            assert_eq!(payload.status, types::Status::Success);
        } else {
            panic!("Invalid payload.");
        }
    }

    #[test]
    fn decode_fragmented_mac_data_ind() {
        // First Fragment
        let data = [
            0xb4, 0xc2, 0x85, 0x10, 0x0, 0x5f, 0x1, 0x2, 0xb1, 0xac, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
            0x2, 0xbb, 0xaa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x27, 0x15, 0x17, 0x0, 0x4, 0x0, 0xfa,
            0xff, 0xfa, 0xff, 0xc9, 0x0, 0xe9, 0x9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2c, 0x1, 0x0, 0x0, 0x6, 0x0, 0xb3, 0x1, 0xb5, 0x1,
            0xb6, 0x1, 0xb9, 0x1, 0xba, 0x1, 0xbc, 0x1, 0xbc, 0x1, 0xbc, 0x1, 0xbc, 0x1, 0xbc, 0x1,
            0xbc, 0x1, 0xba, 0x1, 0xb7, 0x1, 0xb4, 0x1, 0xb1, 0x1, 0xb0, 0x1, 0xac, 0x1, 0xaa, 0x1,
            0xab, 0x1, 0xad, 0x1, 0xac, 0x1, 0xae, 0x1, 0xae, 0x1, 0xaf, 0x1, 0xb1, 0x1, 0xb4, 0x1,
            0xb6, 0x1, 0xb8, 0x1, 0xb7, 0x1, 0xb9, 0x1, 0xbc, 0x1, 0xbe, 0x1, 0xbd, 0x1, 0xbe, 0x1,
            0xbb, 0x1, 0xb5, 0x1, 0xb4, 0x1, 0xb2, 0x1, 0xb1, 0x1, 0xac, 0x1, 0xac, 0x1, 0xab, 0x1,
            0xab, 0x1, 0xaa, 0x1, 0xaa, 0x1, 0xab, 0x1, 0xab, 0x1, 0xad, 0x1, 0xae, 0x1, 0xb1, 0x1,
            0xb2, 0x1, 0xb5, 0x1, 0xb6, 0x1, 0xb6, 0x1, 0xba, 0x1, 0xbc, 0x1, 0xbc, 0x1, 0xbc, 0x1,
            0xbb, 0x1, 0xba, 0x1, 0xb9, 0x1, 0xb7,
        ];

        let mut cursor = Cursor::new(&data[..]);
        let frame1 = frame::MTFrame::try_decode(&mut cursor).unwrap();

        // Second Fragment
        let data = [
            0xb3, 0xc2, 0x85, 0x10, 0x1, 0x5f, 0x1, 0x1, 0xb7, 0x1, 0xb2, 0x1, 0xb0, 0x1, 0xae,
            0x1, 0xac, 0x1, 0xac, 0x1, 0xaa, 0x1, 0xaa, 0x1, 0xab, 0x1, 0xac, 0x1, 0xad, 0x1, 0xaf,
            0x1, 0xb1, 0x1, 0xb3, 0x1, 0xb5, 0x1, 0xb8, 0x1, 0xb9, 0x1, 0xba, 0x1, 0xbb, 0x1, 0xbc,
            0x1, 0xbc, 0x1, 0xbc, 0x1, 0xba, 0x1, 0xba, 0x1, 0xb6, 0x1, 0xb2, 0x1, 0xb2, 0x1, 0xb0,
            0x1, 0xad, 0x1, 0xac, 0x1, 0xab, 0x1, 0xaa, 0x1, 0xab, 0x1, 0xab, 0x1, 0xac, 0x1, 0xae,
            0x1, 0xaf, 0x1, 0xb2, 0x1, 0xb3, 0x1, 0xb5, 0x1, 0xb7, 0x1, 0xb9, 0x1, 0xb9, 0x1, 0xbc,
            0x1, 0xbc, 0x1, 0xbc, 0x1, 0xbc, 0x1, 0xba, 0x1, 0xb9, 0x1, 0xb7, 0x1, 0xb4, 0x1, 0xb2,
            0x1, 0xaf, 0x1, 0xae, 0x1, 0xad, 0x1, 0xab, 0x1, 0xaa, 0x1, 0xab, 0x1, 0xab, 0x1, 0xad,
            0x1, 0xaa, 0x1, 0xaf, 0x1, 0xb0, 0x1, 0xb2, 0x1, 0xb4, 0x1, 0xb6, 0x1, 0xb8, 0x1, 0xba,
            0x1, 0xbb, 0x1, 0xbc, 0x1, 0xbc, 0x1, 0xbb, 0x1, 0xbb, 0x1, 0xb8, 0x1, 0xb7, 0x1, 0xb5,
            0x1, 0xb2, 0x1, 0xb0, 0x1, 0xae, 0x1, 0xad, 0x1, 0xab, 0x1, 0xac, 0x1, 0xab, 0x1, 0xab,
            0x1, 0xac, 0x1, 0xad, 0x1, 0xaf, 0x1,
        ];

        let mut cursor = Cursor::new(&data[..]);
        let frame2 = frame::MTFrame::try_decode(&mut cursor).unwrap();

        let data: Vec<u8> = frame1
            .payload
            .iter()
            .chain(frame2.payload.iter())
            .map(|x| *x)
            .collect();

        assert_eq!(data.len(), 351);

        if let Ok(payload) = subsystem::mac::areq::DataInd::try_decode(&data[..]) {
            assert_eq!(payload.timestamp, 1512743);
            assert_eq!(payload.timestamp2, 4);
            assert_eq!(payload.src_pan_id, 0xfffa);
            assert_eq!(payload.dest_pan_id, 0xfffa);
            assert_eq!(payload.link_quality, 0xc9);
            assert_eq!(payload.correlation, 0x00);
            assert_eq!(payload.rssi, -23);
            assert_eq!(payload.dsn, 0x09);
            assert_eq!(payload.security_level, types::SecurityLevel::NoSecurity);
            assert_eq!(payload.key_id_mode, types::KeyIdMode::NotUsed);
            assert_eq!(payload.key_index, 0x00);
            assert_eq!(payload.frame_counter, 0x00);
            assert_eq!(payload.data_length, 0x012c);
            assert_eq!(payload.ie_length, 0x0000);
            assert_eq!(payload.data_payload.len(), 300);
            assert_eq!(payload.ie_payload.len(), 0);
        } else {
            panic!("Invalid payload.");
        }
    }

    #[test]
    fn decode_encode_mac_reset_req_srsp() {
        let data = [0x1, 0x62, 0x1, 0x0];
        decode_encode_test(&data);
    }

    #[test]
    fn decode_encode_mac_start_req_sreq() {
        let data = [
            0x2a, 0x22, 0x3, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0x0, 0x9, 0x1, 0xf, 0xf, 0x1, 0x0,
            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xf, 0xa, 0xff, 0x3f, 0x0,
        ];
        decode_encode_test(&data);
    }

    #[test]
    fn decode_encode_mac_associate_ind() {
        let data = [
            0x14, 0x42, 0x81, 0x80, 0xbd, 0xc9, 0xb, 0x0, 0x4b, 0x12, 0x0, 0x80, 0x0, 0x0, 0x0,
            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
        ];
        decode_encode_test(&data);
    }

    #[test]
    fn decode_encode_mac_associate_rsp_sreq() {
        let data = [
            0x16, 0x22, 0x50, 0x80, 0xbd, 0xc9, 0xb, 0x0, 0x4b, 0x12, 0x0, 0xb1, 0xac, 0x0, 0x0,
            0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
        ];
        decode_encode_test(&data);
    }

    fn decode_encode_test(data: &[u8]) {
        let mut cursor = Cursor::new(&data[..]);
        let frame = frame::MTFrame::try_decode(&mut cursor).unwrap();

        let mut buffer = Vec::new();
        frame.encode_into(&mut buffer);

        assert_eq!(buffer, data);
    }
}