X-Git-Url: https://code.octet-stream.net/m17rt/blobdiff_plain/e67ea96c8a3d7c23ba29c6ed91ddb451927176a1..4e2358c2ade1278f4835bc263e7df1dd8e74e8c9:/m17core/src/decode.rs diff --git a/m17core/src/decode.rs b/m17core/src/decode.rs index 60c210e..9fd83cd 100755 --- a/m17core/src/decode.rs +++ b/m17core/src/decode.rs @@ -1,8 +1,11 @@ use crate::{ bits::BitsMut, - fec::{self, p_1, p_2}, + fec::{self, p_1, p_2, p_3}, interleave::interleave, - protocol::{LsfFrame, StreamFrame, BERT_SYNC, LSF_SYNC, PACKET_SYNC, STREAM_SYNC}, + protocol::{ + LsfFrame, PacketFrame, PacketFrameCounter, StreamFrame, BERT_SYNC, LSF_SYNC, PACKET_SYNC, + STREAM_SYNC, + }, random::random_xor, }; use log::debug; @@ -85,6 +88,7 @@ pub(crate) fn frame_initial_decode(frame: &[f32] /* length 192 */) -> [u8; 46] { pub(crate) fn parse_lsf(frame: &[f32] /* length 192 */) -> Option { let deinterleaved = frame_initial_decode(frame); + debug!("deinterleaved: {:?}", deinterleaved); let lsf = match fec::decode(&deinterleaved, 240, p_1) { Some(lsf) => LsfFrame(lsf), None => return None, @@ -102,20 +106,6 @@ pub(crate) fn parse_lsf(frame: &[f32] /* length 192 */) -> Option { Some(lsf) } -pub(crate) fn try_lich_decode(type2_bits: &[u8]) -> Option<(u8, [u8; 5])> { - let mut decoded = 0u64; - for (input_idx, input_bytes) in type2_bits.chunks(3).enumerate() { - let mut input: u32 = 0; - for (idx, byte) in input_bytes.iter().enumerate() { - input |= (*byte as u32) << (16 - (8 * idx)); - } - let (val, _dist) = cai_golay::extended::decode(input)?; - decoded |= (val as u64) << ((3 - input_idx) * 12); - } - let b = decoded.to_be_bytes(); - Some((b[7] >> 5, [b[2], b[3], b[4], b[5], b[6]])) -} - pub(crate) fn parse_stream(frame: &[f32] /* length 192 */) -> Option { let deinterleaved = frame_initial_decode(frame); let stream_part = &deinterleaved[12..]; @@ -128,8 +118,11 @@ pub(crate) fn parse_stream(frame: &[f32] /* length 192 */) -> Option Option Option { + let deinterleaved = frame_initial_decode(frame); + let packet = match fec::decode(&deinterleaved, 206, p_3) { + Some(packet) => packet, + None => return None, + }; + let final_frame = (packet[25] & 0x04) > 0; + let number = packet[25] >> 3; + let counter = if final_frame { + PacketFrameCounter::FinalFrame { + payload_len: number as usize, + } + } else { + PacketFrameCounter::Frame { + index: number as usize, + } + }; + Some(PacketFrame { + payload: packet[0..25].try_into().unwrap(), + counter, + }) +} + +pub(crate) fn decode_lich(type2_bits: &[u8]) -> Option<(u8, [u8; 5])> { + let mut decoded = 0u64; + for (input_idx, input_bytes) in type2_bits.chunks(3).enumerate() { + let mut input: u32 = 0; + for (idx, byte) in input_bytes.iter().enumerate() { + input |= (*byte as u32) << (16 - (8 * idx)); + } + let (val, _dist) = cai_golay::extended::decode(input)?; + decoded |= (val as u64) << ((3 - input_idx) * 12); + } + let b = decoded.to_be_bytes(); + Some((b[7] >> 5, [b[2], b[3], b[4], b[5], b[6]])) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_lich_decode() { + let input = [221, 82, 162, 16, 85, 200, 5, 14, 254, 4, 13, 153]; + let expected_counter = 2; + let expected_part = [221, 81, 5, 5, 0]; + assert_eq!(decode_lich(&input), Some((expected_counter, expected_part))); + } +}