// fn stream_assembled_text_block()
// fn stream_gnss_data()
// fn stream_extended_callsign_data()
+
+ // fn stream_tx_ended_early(&self); // underrun/overrun
}
/// via a working implementation of try_clone(). We do not require `Clone` directly
/// as this could not be fulfilled by `TcpStream`.
pub trait Tnc: Read + Write + Sized + Send + 'static {
+ /// Return a copy of this TNC.
+ ///
+ /// `M17App` will use this to create a second instance of the supplied TNC then use
+ /// one of them for reading and one of them for writing, concurrently across two threads.
+ ///
+ /// Implementations do not need to worry about trying to make two simultaneous reads or
+ /// two simultaneous writes do something sensible. `M17App` will not do this and it would
+ /// probably produce garbled KISS messages anyway.
fn try_clone(&mut self) -> Result<Self, TncError>;
+
+ /// Start I/O.
fn start(&mut self) -> Result<(), TncError>;
+
+ /// Shut down I/O - it is assumed we cannot restart.
fn close(&mut self) -> Result<(), TncError>;
}
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;
None
}
}
+
+pub(crate) fn parse_packet(frame: &[f32] /* length 192 */) -> Option<PacketFrame> {
+ 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] & 0x80) > 0;
+ let number = (packet[25] >> 2) & 0x01f;
+ 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,
+ })
+}
(true, mod6 != 5)
}
+pub(crate) fn p_3(step: usize) -> (bool, bool) {
+ let mod4 = step % 4;
+ (true, mod4 != 3)
+}
+
fn best_previous(table: &[[u8; 32]; 244], step: usize, state: usize) -> u8 {
if step == 0 {
if state == 0 {
-use crate::decode::{parse_lsf, parse_stream, sync_burst_correlation, SyncBurst, SYNC_THRESHOLD};
+use crate::decode::{
+ parse_lsf, parse_packet, parse_stream, sync_burst_correlation, SyncBurst, SYNC_THRESHOLD,
+};
use crate::protocol::Frame;
use crate::shaping::RRC_48K;
use log::debug;
}
}
SyncBurst::Packet => {
- debug!("Found PACKET at sample {} diff {}", start_sample, c.diff)
+ debug!("Found PACKET at sample {} diff {}", start_sample, c.diff);
+ if let Some(frame) = parse_packet(&pkt_samples) {
+ self.suppress = 191 * 10;
+ return Some(Frame::Packet(frame));
+ }
}
}
}