X-Git-Url: https://code.octet-stream.net/m17rt/blobdiff_plain/e67ea96c8a3d7c23ba29c6ed91ddb451927176a1..4cfda08117c4288a5408d45db1ef4be82f4facaa:/m17core/src/decode.rs?ds=sidebyside diff --git a/m17core/src/decode.rs b/m17core/src/decode.rs index 60c210e..115ff63 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; @@ -59,6 +62,7 @@ pub(crate) fn sync_burst_correlation(target: [i8; 8], samples: &[f32]) -> (f32, if gain < SYNC_MIN_GAIN { return (f32::MAX, gain, shift); } + let mut diff = 0.0; for i in 0..8 { let sym_diff = (((samples[i * 10] - shift) / gain) - target[i] as f32).abs(); @@ -85,12 +89,13 @@ 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, }; debug!("full lsf: {:?}", lsf.0); - let crc = lsf.crc(); + let crc = lsf.check_crc(); debug!("recv crc: {:04X}", crc); debug!("destination: {:?}", lsf.destination()); debug!("source: {:?}", lsf.source()); @@ -102,20 +107,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 +119,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, + }; + // TODO: the spec is inconsistent about which bit in packet[25] is EOF + // https://github.com/M17-Project/M17_spec/issues/147 + 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))); + } +}