+ while let Some(kiss_frame) = self.kiss_buffer.next_frame() {
+ let Ok(port) = kiss_frame.port() else {
+ 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;
+ }
+ }
+ }