X-Git-Url: https://code.octet-stream.net/m17rt/blobdiff_plain/9058451e46e4d36264282abe381aa9b6fd2c773f..253c89360003ac72c4f7078c03af973c58a1b129:/m17core/src/tnc.rs diff --git a/m17core/src/tnc.rs b/m17core/src/tnc.rs index 0d8bf4a..7851948 100644 --- a/m17core/src/tnc.rs +++ b/m17core/src/tnc.rs @@ -1,3 +1,4 @@ +use crate::address::{Address, Callsign}; use crate::kiss::{KissBuffer, KissFrame, PORT_PACKET_BASIC, PORT_PACKET_FULL, PORT_STREAM}; use crate::modem::ModulatorFrame; use crate::protocol::{ @@ -211,6 +212,7 @@ impl SoftTnc { } 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); @@ -251,7 +253,7 @@ impl SoftTnc { } 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)) } @@ -315,8 +317,86 @@ impl SoftTnc { continue; }; if port == PORT_PACKET_BASIC { + if self.packet_full { + continue; + } + let mut pending = PendingPacket::new(); + pending.app_data[0] = 0x00; // RAW + let Ok(mut len) = kiss_frame.decode_payload(&mut pending.app_data[1..]) else { + continue; + }; + len += 1; // for RAW prefix + let packet_crc = crate::crc::m17_crc(&pending.app_data[0..len]); + pending.app_data[len..len + 2].copy_from_slice(&packet_crc.to_be_bytes()); + pending.app_data_len = len + 2; + pending.lsf = Some(LsfFrame::new_packet( + &Address::Callsign(Callsign(b"M17RT-PKT".clone())), + &Address::Broadcast, + )); + self.packet_queue[self.packet_next] = pending; + self.packet_next = (self.packet_next + 1) % 4; + if self.packet_next == self.packet_curr { + self.packet_full = true; + } } else if port == PORT_PACKET_FULL { + if self.packet_full { + continue; + } + let mut pending = PendingPacket::new(); + let mut payload = [0u8; 855]; + let Ok(len) = kiss_frame.decode_payload(&mut payload) else { + continue; + }; + if len < 33 { + continue; + } + let mut lsf = LsfFrame([0u8; 30]); + lsf.0.copy_from_slice(&payload[0..30]); + if lsf.check_crc() != 0 { + continue; + } + pending.lsf = Some(lsf); + let app_data_len = len - 30; + pending.app_data[0..app_data_len].copy_from_slice(&payload[30..]); + pending.app_data_len = app_data_len; + self.packet_queue[self.packet_next] = pending; + self.packet_next = (self.packet_next + 1) % 4; + if self.packet_next == self.packet_curr { + self.packet_full = true; + } } else if port == PORT_STREAM { + 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 @@ -404,6 +484,15 @@ struct PendingPacket { } impl PendingPacket { + fn new() -> Self { + Self { + lsf: None, + app_data: [0u8; 825], + app_data_len: 0, + app_data_transmitted: 0, + } + } + /// Returns next frame, not including preamble or EOT. /// /// False means all data frames have been sent.