]> code.octet-stream.net Git - m17rt/commitdiff
Add and test error if packet payload is too large
authorThomas Karpiniec <tom.karpiniec@outlook.com>
Sat, 1 Feb 2025 03:16:44 +0000 (14:16 +1100)
committerThomas Karpiniec <tom.karpiniec@outlook.com>
Sat, 1 Feb 2025 03:16:44 +0000 (14:16 +1100)
m17app/src/app.rs
m17app/src/error.rs
m17app/src/lib.rs
m17app/src/test_util.rs [new file with mode: 0644]
tools/m17rt-txpacket/src/main.rs

index 7f17df64a4f5898ba1de7cff2b0b364484f7bc55..0abfab640b51937b9076b45cea922ea43c4e954a 100644 (file)
@@ -1,4 +1,5 @@
 use crate::adapter::{PacketAdapter, StreamAdapter};
+use crate::error::M17Error;
 use crate::link_setup::LinkSetup;
 use crate::tnc::Tnc;
 use crate::{LsfFrame, PacketType, StreamFrame};
@@ -85,11 +86,18 @@ pub struct TxHandle {
 }
 
 impl TxHandle {
-    pub fn transmit_packet(&self, link_setup: &LinkSetup, packet_type: PacketType, payload: &[u8]) {
+    pub fn transmit_packet(
+        &self,
+        link_setup: &LinkSetup,
+        packet_type: PacketType,
+        payload: &[u8],
+    ) -> Result<(), M17Error> {
         let (pack_type, pack_type_len) = packet_type.as_proto();
         if pack_type_len + payload.len() > 823 {
-            // TODO: error for invalid transmission type
-            return;
+            return Err(M17Error::PacketTooLarge {
+                provided: payload.len(),
+                capacity: 823 - pack_type_len,
+            });
         }
         let mut full_payload = vec![];
         full_payload.extend_from_slice(&pack_type[0..pack_type_len]);
@@ -98,6 +106,7 @@ impl TxHandle {
         full_payload.extend_from_slice(&crc.to_be_bytes());
         let kiss_frame = KissFrame::new_full_packet(&link_setup.raw.0, &full_payload).unwrap();
         let _ = self.event_tx.send(TncControlEvent::Kiss(kiss_frame));
+        Ok(())
     }
 
     pub fn transmit_stream_start(&self, link_setup: &LinkSetup) {
@@ -283,3 +292,33 @@ fn spawn_writer<T: Tnc>(mut tnc: T, event_rx: mpsc::Receiver<TncControlEvent>) {
         }
     });
 }
+
+#[cfg(test)]
+mod tests {
+    use crate::{link_setup::M17Address, test_util::NullTnc};
+
+    use super::*;
+
+    #[test]
+    fn packet_payload_len() {
+        let app = M17App::new(NullTnc);
+        let res = app.tx().transmit_packet(
+            &LinkSetup::new_packet(&M17Address::new_broadcast(), &M17Address::new_broadcast()),
+            PacketType::Raw,
+            &[0u8; 100],
+        );
+        assert_eq!(res, Ok(()));
+        let res = app.tx().transmit_packet(
+            &LinkSetup::new_packet(&M17Address::new_broadcast(), &M17Address::new_broadcast()),
+            PacketType::Raw,
+            &[0u8; 900],
+        );
+        assert_eq!(
+            res,
+            Err(M17Error::PacketTooLarge {
+                provided: 900,
+                capacity: 822
+            })
+        );
+    }
+}
index 36d5ac07f95943554760666a2d688f5ed37b798a..acbf397f28c1d4a6f247a59b6cf8e1c0833d0ab2 100644 (file)
@@ -1,6 +1,6 @@
 use thiserror::Error;
 
-#[derive(Debug, Error)]
+#[derive(Debug, Error, PartialEq, Eq, Clone)]
 pub enum M17Error {
     #[error("given callsign contains at least one character invalid in M17: {0}")]
     InvalidCallsignCharacters(char),
@@ -16,4 +16,9 @@ pub enum M17Error {
 
     #[error("unable to set up RTL-SDR receiver")]
     RtlSdrInit,
+
+    #[error(
+        "provided packet payload is too large: provided {provided} bytes, capacity {capacity}"
+    )]
+    PacketTooLarge { provided: usize, capacity: usize },
 }
index 91135151938e23d7db488380ed2b62cb88868d22..1881df33b94a19542938e7bbe813818d547f0cf2 100755 (executable)
@@ -10,5 +10,8 @@ pub mod soundcard;
 pub mod soundmodem;
 pub mod tnc;
 
+#[cfg(test)]
+mod test_util;
+
 // Protocol definitions needed to implement stream and packet adapters or create fully custom LSFs
 pub use m17core::protocol::{LsfFrame, PacketType, StreamFrame};
diff --git a/m17app/src/test_util.rs b/m17app/src/test_util.rs
new file mode 100644 (file)
index 0000000..ea654f1
--- /dev/null
@@ -0,0 +1,36 @@
+use std::io::{Read, Write};
+
+use crate::tnc::Tnc;
+
+#[derive(Clone)]
+pub(crate) struct NullTnc;
+
+impl Tnc for NullTnc {
+    fn try_clone(&mut self) -> Result<Self, crate::tnc::TncError> {
+        Ok(self.clone())
+    }
+
+    fn start(&mut self) -> Result<(), crate::tnc::TncError> {
+        Ok(())
+    }
+
+    fn close(&mut self) -> Result<(), crate::tnc::TncError> {
+        Ok(())
+    }
+}
+
+impl Write for NullTnc {
+    fn write(&mut self, _buf: &[u8]) -> std::io::Result<usize> {
+        Ok(0)
+    }
+
+    fn flush(&mut self) -> std::io::Result<()> {
+        Ok(())
+    }
+}
+
+impl Read for NullTnc {
+    fn read(&mut self, _buf: &mut [u8]) -> std::io::Result<usize> {
+        Ok(0)
+    }
+}
index 916edf2f8773600678148457507d476dd670824b..3e72e230cf0dd9ddfe01b4bd40651fc89577760e 100644 (file)
@@ -20,7 +20,8 @@ fn main() {
     let link_setup = LinkSetup::new_packet(&source, &destination);
     let payload = b"Hello, world!";
     app.tx()
-        .transmit_packet(&link_setup, PacketType::Sms, payload);
+        .transmit_packet(&link_setup, PacketType::Sms, payload)
+        .unwrap();
 
     std::thread::sleep(std::time::Duration::from_secs(1));
     app.close();