]> code.octet-stream.net Git - m17rt/blobdiff - m17core/src/tnc.rs
Support for baseband output to a soundcard
[m17rt] / m17core / src / tnc.rs
index d4e07b4e8344dd6ad9709b146c9c8592d042f3f9..785194828f49c394dd52fe0102171e77ecdfd176 100644 (file)
@@ -212,6 +212,7 @@ impl SoftTnc {
     }
 
     pub fn set_tx_end_time(&mut self, in_samples: usize) {
     }
 
     pub fn set_tx_end_time(&mut self, in_samples: usize) {
+        log::debug!("tnc has been told that tx will complete in {in_samples} samples");
         match self.state {
             State::TxEnding => {
                 self.state = State::TxEndingAtTime(self.now + in_samples as u64);
         match self.state {
             State::TxEnding => {
                 self.state = State::TxEndingAtTime(self.now + in_samples as u64);
@@ -252,7 +253,7 @@ impl SoftTnc {
                 }
                 self.stream_curr = (self.stream_curr + 1) % 8;
                 if frame.end_of_stream {
                 }
                 self.stream_curr = (self.stream_curr + 1) % 8;
                 if frame.end_of_stream {
-                    self.state = State::Idle;
+                    self.state = State::TxStreamSentEndOfStream;
                 }
                 Some(ModulatorFrame::Stream(frame))
             }
                 }
                 Some(ModulatorFrame::Stream(frame))
             }
@@ -364,7 +365,38 @@ impl SoftTnc {
                     self.packet_full = true;
                 }
             } else if port == PORT_STREAM {
                     self.packet_full = true;
                 }
             } else if port == PORT_STREAM {
-                // TODO: handle port 2
+                let mut payload = [0u8; 30];
+                let Ok(len) = kiss_frame.decode_payload(&mut payload) else {
+                    continue;
+                };
+                if len < 26 {
+                    log::debug!("payload len too short");
+                    continue;
+                }
+                if len == 30 {
+                    let lsf = LsfFrame(payload);
+                    if lsf.check_crc() != 0 {
+                        continue;
+                    }
+                    self.stream_pending_lsf = Some(lsf);
+                } else {
+                    if self.stream_full {
+                        log::debug!("stream full");
+                        continue;
+                    }
+                    let frame_num_part = u16::from_be_bytes([payload[6], payload[7]]);
+                    self.stream_queue[self.stream_next] = StreamFrame {
+                        lich_idx: payload[5] >> 5,
+                        lich_part: payload[0..5].try_into().unwrap(),
+                        frame_number: frame_num_part & 0x7fff,
+                        end_of_stream: frame_num_part & 0x8000 > 0,
+                        stream_data: payload[8..24].try_into().unwrap(),
+                    };
+                    self.stream_next = (self.stream_next + 1) % 8;
+                    if self.stream_next == self.stream_curr {
+                        self.stream_full = true;
+                    }
+                }
             }
         }
         n
             }
         }
         n