]> code.octet-stream.net Git - m17rt/blobdiff - m17core/src/kiss.rs
Fix timing bugs and add documentation
[m17rt] / m17core / src / kiss.rs
index 3770784030e977be9dd0e72414067c08e43c3d1f..37d3d0ba31b57aa53c12f4f9de904ef4d3bf2278 100644 (file)
@@ -1,3 +1,5 @@
+use crate::protocol::StreamFrame;
+
 // Note FEND and FESC both have the top two bits set. In the header byte this corresponds
 // to high port numbers which are never used by M17 so we needn't bother (un)escaping it.
 
 // Note FEND and FESC both have the top two bits set. In the header byte this corresponds
 // to high port numbers which are never used by M17 so we needn't bother (un)escaping it.
 
@@ -117,14 +119,7 @@ impl KissFrame {
     }
 
     /// Transmit a segment of data in a stream transfer (e.g. voice).
     }
 
     /// Transmit a segment of data in a stream transfer (e.g. voice).
-    ///
-    /// A data payload of 26 bytes including metadata must be provided. This must follow
-    /// exactly the prescribed format (H.5.2 in the spec). The TNC will be watching for
-    /// the EOS flag to know that this transmission has ended.
-    pub fn new_stream_data(stream_data: &[u8]) -> Result<Self, KissError> {
-        if stream_data.len() != 26 {
-            return Err(KissError::StreamDataWrongSize);
-        }
+    pub fn new_stream_data(frame: &StreamFrame) -> Result<Self, KissError> {
         let mut data = [0u8; MAX_FRAME_LEN];
         let mut i = 0;
         push(&mut data, &mut i, FEND);
         let mut data = [0u8; MAX_FRAME_LEN];
         let mut i = 0;
         push(&mut data, &mut i, FEND);
@@ -133,9 +128,25 @@ impl KissFrame {
             &mut i,
             kiss_header(PORT_STREAM, KissCommand::DataFrame.proto_value()),
         );
             &mut i,
             kiss_header(PORT_STREAM, KissCommand::DataFrame.proto_value()),
         );
-        i += escape(stream_data, &mut data[i..]);
-        push(&mut data, &mut i, FEND);
 
 
+        // 5 bytes LICH content
+        i += escape(&frame.lich_part, &mut data[i..]);
+        // 1 byte LICH metadata
+        i += escape(&[frame.lich_idx << 5], &mut data[i..]);
+
+        // 2 bytes frame number/EOS + 16 bytes payload + 2 bytes CRC
+        let mut inner_data = [0u8; 20];
+        let frame_num = frame.frame_number.to_be_bytes();
+        inner_data[0] = frame_num[0] | if frame.end_of_stream { 0x80 } else { 0 };
+        inner_data[1] = frame_num[1];
+        inner_data[2..18].copy_from_slice(&frame.stream_data);
+        let crc = crate::crc::m17_crc(&inner_data[0..18]);
+        let crc_be = crc.to_be_bytes();
+        inner_data[18] = crc_be[0];
+        inner_data[19] = crc_be[1];
+        i += escape(&inner_data, &mut data[i..]);
+
+        push(&mut data, &mut i, FEND);
         Ok(KissFrame { data, len: i })
     }
 
         Ok(KissFrame { data, len: i })
     }
 
@@ -204,15 +215,13 @@ impl KissFrame {
             .iter()
             .enumerate()
             .skip_while(|(_, b)| **b == FEND)
             .iter()
             .enumerate()
             .skip_while(|(_, b)| **b == FEND)
-            .skip(1)
-            .next()
+            .nth(1)
             .ok_or(KissError::MalformedKissFrame)?
             .0;
         let end = self.data[start..]
             .iter()
             .enumerate()
             .ok_or(KissError::MalformedKissFrame)?
             .0;
         let end = self.data[start..]
             .iter()
             .enumerate()
-            .skip_while(|(_, b)| **b != FEND)
-            .next()
+            .find(|(_, b)| **b == FEND)
             .ok_or(KissError::MalformedKissFrame)?
             .0
             + start;
             .ok_or(KissError::MalformedKissFrame)?
             .0
             + start;
@@ -226,13 +235,11 @@ impl KissFrame {
 
     /// Return the header byte of the KISS frame, skipping over 0 or more prepended FENDs.
     fn header_byte(&self) -> Result<u8, KissError> {
 
     /// Return the header byte of the KISS frame, skipping over 0 or more prepended FENDs.
     fn header_byte(&self) -> Result<u8, KissError> {
-        Ok(self
-            .data
+        self.data
             .iter()
             .iter()
-            .skip_while(|b| **b == FEND)
-            .next()
+            .find(|b| **b != FEND)
             .cloned()
             .cloned()
-            .ok_or(KissError::MalformedKissFrame)?)
+            .ok_or(KissError::MalformedKissFrame)
     }
 }
 
     }
 }
 
@@ -382,13 +389,18 @@ impl KissBuffer {
     }
 }
 
     }
 }
 
-#[derive(Debug)]
+impl Default for KissBuffer {
+    fn default() -> Self {
+        Self::new()
+    }
+}
+
+#[derive(Debug, PartialEq, Eq, Clone)]
 pub enum KissError {
     MalformedKissFrame,
     UnsupportedKissCommand,
     PayloadTooBig,
     LsfWrongSize,
 pub enum KissError {
     MalformedKissFrame,
     UnsupportedKissCommand,
     PayloadTooBig,
     LsfWrongSize,
-    StreamDataWrongSize,
 }
 
 fn escape(src: &[u8], dst: &mut [u8]) -> usize {
 }
 
 fn escape(src: &[u8], dst: &mut [u8]) -> usize {
@@ -531,7 +543,7 @@ mod tests {
     fn test_buffer_double() {
         let mut buffer = KissBuffer::new();
         let buf = buffer.buf_remaining();
     fn test_buffer_double() {
         let mut buffer = KissBuffer::new();
         let buf = buffer.buf_remaining();
-        buf[0..8].copy_from_slice(&[FEND, 0x10, 0x01, FEND, FEND, 0x20, 02, FEND]);
+        buf[0..8].copy_from_slice(&[FEND, 0x10, 0x01, FEND, FEND, 0x20, 0x02, FEND]);
         buffer.did_write(8);
 
         let next = buffer.next_frame().unwrap();
         buffer.did_write(8);
 
         let next = buffer.next_frame().unwrap();
@@ -545,7 +557,7 @@ mod tests {
     fn test_buffer_double_shared_fend() {
         let mut buffer = KissBuffer::new();
         let buf = buffer.buf_remaining();
     fn test_buffer_double_shared_fend() {
         let mut buffer = KissBuffer::new();
         let buf = buffer.buf_remaining();
-        buf[0..7].copy_from_slice(&[FEND, 0x10, 0x01, FEND, 0x20, 02, FEND]);
+        buf[0..7].copy_from_slice(&[FEND, 0x10, 0x01, FEND, 0x20, 0x02, FEND]);
         buffer.did_write(7);
 
         let next = buffer.next_frame().unwrap();
         buffer.did_write(7);
 
         let next = buffer.next_frame().unwrap();
@@ -559,7 +571,7 @@ mod tests {
     fn test_buffer_extra_fend() {
         let mut buffer = KissBuffer::new();
         let buf = buffer.buf_remaining();
     fn test_buffer_extra_fend() {
         let mut buffer = KissBuffer::new();
         let buf = buffer.buf_remaining();
-        buf[0..10].copy_from_slice(&[FEND, FEND, FEND, 0x10, 0x01, FEND, FEND, 0x20, 02, FEND]);
+        buf[0..10].copy_from_slice(&[FEND, FEND, FEND, 0x10, 0x01, FEND, FEND, 0x20, 0x02, FEND]);
         buffer.did_write(10);
 
         let next = buffer.next_frame().unwrap();
         buffer.did_write(10);
 
         let next = buffer.next_frame().unwrap();