]> code.octet-stream.net Git - m17rt/blobdiff - m17core/src/decode.rs
Fix packet encoding
[m17rt] / m17core / src / decode.rs
index de131246189bee791e9a0267cd394d2cd07229b0..6c8e02bfdc1431448a50d73c7886d3d89ee625cf 100755 (executable)
@@ -62,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);
     }
     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();
     let mut diff = 0.0;
     for i in 0..8 {
         let sym_diff = (((samples[i * 10] - shift) / gain) - target[i] as f32).abs();
@@ -94,7 +95,7 @@ pub(crate) fn parse_lsf(frame: &[f32] /* length 192 */) -> Option<LsfFrame> {
         None => return None,
     };
     debug!("full lsf: {:?}", lsf.0);
         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());
     debug!("recv crc: {:04X}", crc);
     debug!("destination: {:?}", lsf.destination());
     debug!("source: {:?}", lsf.source());
@@ -106,20 +107,6 @@ pub(crate) fn parse_lsf(frame: &[f32] /* length 192 */) -> Option<LsfFrame> {
     Some(lsf)
 }
 
     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<StreamFrame> {
     let deinterleaved = frame_initial_decode(frame);
     let stream_part = &deinterleaved[12..];
 pub(crate) fn parse_stream(frame: &[f32] /* length 192 */) -> Option<StreamFrame> {
     let deinterleaved = frame_initial_decode(frame);
     let stream_part = &deinterleaved[12..];
@@ -132,8 +119,11 @@ pub(crate) fn parse_stream(frame: &[f32] /* length 192 */) -> Option<StreamFrame
     let frame_num = frame_num & 0x7fff; // higher layer has to handle wraparound
     debug!("frame number: {frame_num}, codec2: {:?}", &stream[2..18]);
 
     let frame_num = frame_num & 0x7fff; // higher layer has to handle wraparound
     debug!("frame number: {frame_num}, codec2: {:?}", &stream[2..18]);
 
-    if let Some((counter, part)) = try_lich_decode(&deinterleaved[0..12]) {
-        debug!("LICH: received part {counter}");
+    if let Some((counter, part)) = decode_lich(&deinterleaved[0..12]) {
+        debug!(
+            "LICH: received part {counter} part {part:?} from raw {:?}",
+            &deinterleaved[0..12]
+        );
         Some(StreamFrame {
             lich_idx: counter,
             lich_part: part,
         Some(StreamFrame {
             lich_idx: counter,
             lich_part: part,
@@ -152,8 +142,10 @@ pub(crate) fn parse_packet(frame: &[f32] /* length 192 */) -> Option<PacketFrame
         Some(packet) => packet,
         None => return None,
     };
         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] & 0x80) > 0;
     let final_frame = (packet[25] & 0x80) > 0;
-    let number = (packet[25] >> 2) & 0x01f;
+    let number = (packet[25] >> 2) & 0x1f;
     let counter = if final_frame {
         PacketFrameCounter::FinalFrame {
             payload_len: number as usize,
     let counter = if final_frame {
         PacketFrameCounter::FinalFrame {
             payload_len: number as usize,
@@ -168,3 +160,30 @@ pub(crate) fn parse_packet(frame: &[f32] /* length 192 */) -> Option<PacketFrame
         counter,
     })
 }
         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)));
+    }
+}