From: Thomas Karpiniec <tom.karpiniec@outlook.com>
Date: Mon, 20 Jan 2025 09:57:46 +0000 (+1100)
Subject: Track preamble and EOT and estimate DCD
X-Git-Tag: v0.1.0~9
X-Git-Url: https://code.octet-stream.net/m17rt/commitdiff_plain/d5f46a2d5d294c5a4287780dd609475fa73df9a8?hp=bb98d1726f35a41236b66bcf9fa0a8fa36633342

Track preamble and EOT and estimate DCD
---

diff --git a/m17core/src/decode.rs b/m17core/src/decode.rs
index 86567d9..911d673 100755
--- a/m17core/src/decode.rs
+++ b/m17core/src/decode.rs
@@ -3,8 +3,8 @@ use crate::{
     fec::{self, p_1, p_2, p_3},
     interleave::interleave,
     protocol::{
-        LsfFrame, PacketFrame, PacketFrameCounter, StreamFrame, BERT_SYNC, LSF_SYNC, PACKET_SYNC,
-        STREAM_SYNC,
+        LsfFrame, PacketFrame, PacketFrameCounter, StreamFrame, BERT_SYNC, END_OF_TRANSMISSION,
+        LSF_SYNC, PACKET_SYNC, PREAMBLE, STREAM_SYNC,
     },
     random::random_xor,
 };
@@ -33,6 +33,8 @@ pub(crate) enum SyncBurst {
     Bert,
     Stream,
     Packet,
+    Preamble,
+    EndOfTransmission,
 }
 
 impl SyncBurst {
@@ -42,6 +44,8 @@ impl SyncBurst {
             Self::Bert => BERT_SYNC,
             Self::Stream => STREAM_SYNC,
             Self::Packet => PACKET_SYNC,
+            Self::Preamble => PREAMBLE,
+            Self::EndOfTransmission => END_OF_TRANSMISSION,
         }
     }
 }
diff --git a/m17core/src/modem.rs b/m17core/src/modem.rs
index b333ef5..8cbd003 100644
--- a/m17core/src/modem.rs
+++ b/m17core/src/modem.rs
@@ -29,6 +29,8 @@ pub struct SoftDemodulator {
     sample: u64,
     /// Remaining samples to read in before attempting to decode the current candidate
     samples_until_decode: Option<u16>,
+    /// Do we think there is a data carrier, i.e., channel in use? If so, at what sample does it expire?
+    dcd: Option<u64>,
 }
 
 impl SoftDemodulator {
@@ -41,6 +43,25 @@ impl SoftDemodulator {
             candidate: None,
             sample: 0,
             samples_until_decode: None,
+            dcd: None,
+        }
+    }
+}
+
+impl SoftDemodulator {
+    fn dcd_until(&mut self, end_sample: u64) {
+        if self.dcd.is_none() {
+            debug!("SoftDemodulator DCD on");
+        }
+        self.dcd = Some(end_sample);
+    }
+
+    fn check_dcd(&mut self) {
+        if let Some(end_sample) = self.dcd {
+            if self.sample > end_sample {
+                self.dcd = None;
+                debug!("SoftDemodulator DCD off");
+            }
         }
     }
 }
@@ -59,6 +80,7 @@ impl Demodulator for SoftDemodulator {
         self.rx_cursor = (self.rx_cursor + 1) % 1920;
 
         self.sample += 1;
+        self.check_dcd();
 
         if let Some(samples_until_decode) = self.samples_until_decode {
             let sud = samples_until_decode - 1;
@@ -97,6 +119,9 @@ impl Demodulator for SoftDemodulator {
                             return Some(Frame::Packet(frame));
                         }
                     }
+                    SyncBurst::Preamble | SyncBurst::EndOfTransmission => {
+                        // should never be chosen as a candidate
+                    }
                 }
             }
         }
@@ -107,6 +132,15 @@ impl Demodulator for SoftDemodulator {
             burst_window[i] = self.rx_win[c];
         }
 
+        for burst in [SyncBurst::Preamble, SyncBurst::EndOfTransmission] {
+            let (diff, _, _) = sync_burst_correlation(burst.target(), &burst_window);
+            if diff < SYNC_THRESHOLD {
+                // arbitrary choice, 240 samples = 5ms
+                // these bursts keep repeating so it will keep pushing out the DCD end time
+                self.dcd_until(self.sample + 240);
+            }
+        }
+
         for burst in [
             SyncBurst::Lsf,
             SyncBurst::Bert,
@@ -148,6 +182,8 @@ impl Demodulator for SoftDemodulator {
                     self.sample - c.age as u64,
                     c.diff
                 );
+                // After any of these frame types you would expect to see a full EOT
+                self.dcd_until(self.sample + 1920 + 1920);
             }
         }
 
diff --git a/m17core/src/protocol.rs b/m17core/src/protocol.rs
index f2e154e..e4b3b15 100755
--- a/m17core/src/protocol.rs
+++ b/m17core/src/protocol.rs
@@ -4,6 +4,8 @@ pub(crate) const LSF_SYNC: [i8; 8] = [1, 1, 1, 1, -1, -1, 1, -1];
 pub(crate) const BERT_SYNC: [i8; 8] = [-1, 1, -1, -1, 1, 1, 1, 1];
 pub(crate) const STREAM_SYNC: [i8; 8] = [-1, -1, -1, -1, 1, 1, -1, 1];
 pub(crate) const PACKET_SYNC: [i8; 8] = [1, -1, 1, 1, -1, -1, -1, -1];
+pub(crate) const PREAMBLE: [i8; 8] = [1, -1, 1, -1, 1, -1, 1, -1];
+pub(crate) const END_OF_TRANSMISSION: [i8; 8] = [1, 1, 1, 1, 1, 1, -1, 1];
 
 #[derive(Debug, Clone, PartialEq, Eq, Copy)]
 pub enum Mode {