瀏覽代碼

Better impls defmt for some structs

Sometimer, the defmt implementation was not readable when debugging.
I changed it such that the defmt implelementation matches the Display
implementation (which was more readable).
Thibaut Vandervelden 2 年之前
父節點
當前提交
4b1e8b174c
共有 6 個文件被更改,包括 227 次插入21 次删除
  1. 29 2
      src/storage/assembler.rs
  2. 63 11
      src/wire/ieee802154.rs
  3. 14 1
      src/wire/ipv6.rs
  4. 70 3
      src/wire/sixlowpan.rs
  5. 30 2
      src/wire/tcp.rs
  6. 21 2
      src/wire/udp.rs

+ 29 - 2
src/storage/assembler.rs

@@ -16,7 +16,6 @@ impl std::error::Error for TooManyHolesError {}
 
 /// A contiguous chunk of absent data, followed by a contiguous chunk of present data.
 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
-#[cfg_attr(feature = "defmt", derive(defmt::Format))]
 struct Contig {
     hole_size: usize,
     data_size: usize,
@@ -37,6 +36,21 @@ impl fmt::Display for Contig {
     }
 }
 
+#[cfg(feature = "defmt")]
+impl defmt::Format for Contig {
+    fn format(&self, fmt: defmt::Formatter) {
+        if self.has_hole() {
+            defmt::write!(fmt, "({})", self.hole_size);
+        }
+        if self.has_hole() && self.has_data() {
+            defmt::write!(fmt, " ");
+        }
+        if self.has_data() {
+            defmt::write!(fmt, "{}", self.data_size);
+        }
+    }
+}
+
 impl Contig {
     const fn empty() -> Contig {
         Contig {
@@ -81,7 +95,6 @@ impl Contig {
 ///
 /// Currently, up to a hardcoded limit of 4 or 32 holes can be tracked in the buffer.
 #[derive(Debug, PartialEq, Eq, Clone)]
-#[cfg_attr(feature = "defmt", derive(defmt::Format))]
 pub struct Assembler {
     contigs: [Contig; ASSEMBLER_MAX_SEGMENT_COUNT],
 }
@@ -100,6 +113,20 @@ impl fmt::Display for Assembler {
     }
 }
 
+#[cfg(feature = "defmt")]
+impl defmt::Format for Assembler {
+    fn format(&self, fmt: defmt::Formatter) {
+        defmt::write!(fmt, "[ ");
+        for contig in self.contigs.iter() {
+            if !contig.has_data() {
+                break;
+            }
+            defmt::write!(fmt, "{} ", contig);
+        }
+        defmt::write!(fmt, "]");
+    }
+}
+
 // Invariant on Assembler::contigs:
 // - There's an index `i` where all contigs before have data, and all contigs after don't (are unused).
 // - All contigs with data must have hole_size != 0, except the first.

+ 63 - 11
src/wire/ieee802154.rs

@@ -66,7 +66,6 @@ impl fmt::Display for AddressingMode {
 
 /// A IEEE 802.15.4 PAN.
 #[derive(Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)]
-#[cfg_attr(feature = "defmt", derive(defmt::Format))]
 pub struct Pan(pub u16);
 
 impl Pan {
@@ -80,6 +79,19 @@ impl Pan {
     }
 }
 
+impl fmt::Display for Pan {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "{:0x}", self.0)
+    }
+}
+
+#[cfg(feature = "defmt")]
+impl defmt::Format for Pan {
+    fn format(&self, fmt: defmt::Formatter) {
+        defmt::write!(fmt, "{:02x}", self.0)
+    }
+}
+
 /// A IEEE 802.15.4 address.
 #[derive(Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)]
 pub enum Address {
@@ -759,16 +771,56 @@ impl<T: AsRef<[u8]> + AsMut<[u8]>> Frame<T> {
 
 impl<T: AsRef<[u8]>> fmt::Display for Frame<T> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(
-            f,
-            "IEEE802.15.4 frame type={} seq={:2x?} dst_pan={:x?} dest={:x?} src_pan={:?} src={:x?}",
-            self.frame_type(),
-            self.sequence_number(),
-            self.dst_pan_id(),
-            self.dst_addr(),
-            self.src_pan_id(),
-            self.src_addr(),
-        )
+        write!(f, "IEEE802.15.4 frame type={}", self.frame_type())?;
+
+        if let Some(seq) = self.sequence_number() {
+            write!(f, " seq={:02x}", seq)?;
+        }
+
+        if let Some(pan) = self.dst_pan_id() {
+            write!(f, " dst-pan={}", pan)?;
+        }
+
+        if let Some(pan) = self.src_pan_id() {
+            write!(f, " src-pan={}", pan)?;
+        }
+
+        if let Some(addr) = self.dst_addr() {
+            write!(f, " dst={}", addr)?;
+        }
+
+        if let Some(addr) = self.src_addr() {
+            write!(f, " src={}", addr)?;
+        }
+
+        Ok(())
+    }
+}
+
+#[cfg(feature = "defmt")]
+impl<T: AsRef<[u8]>> defmt::Format for Frame<T> {
+    fn format(&self, f: defmt::Formatter) {
+        defmt::write!(f, "IEEE802.15.4 frame type={}", self.frame_type());
+
+        if let Some(seq) = self.sequence_number() {
+            defmt::write!(f, " seq={:02x}", seq);
+        }
+
+        if let Some(pan) = self.dst_pan_id() {
+            defmt::write!(f, " dst-pan={}", pan);
+        }
+
+        if let Some(pan) = self.src_pan_id() {
+            defmt::write!(f, " src-pan={}", pan);
+        }
+
+        if let Some(addr) = self.dst_addr() {
+            defmt::write!(f, " dst={}", addr);
+        }
+
+        if let Some(addr) = self.src_addr() {
+            defmt::write!(f, " src={}", addr);
+        }
     }
 }
 

+ 14 - 1
src/wire/ipv6.rs

@@ -721,7 +721,6 @@ impl<T: AsRef<[u8]>> AsRef<[u8]> for Packet<T> {
 
 /// A high-level representation of an Internet Protocol version 6 packet header.
 #[derive(Debug, PartialEq, Eq, Clone, Copy)]
-#[cfg_attr(feature = "defmt", derive(defmt::Format))]
 pub struct Repr {
     /// IPv6 address of the source node.
     pub src_addr: Address,
@@ -783,6 +782,20 @@ impl fmt::Display for Repr {
     }
 }
 
+#[cfg(feature = "defmt")]
+impl defmt::Format for Repr {
+    fn format(&self, fmt: defmt::Formatter) {
+        defmt::write!(
+            fmt,
+            "IPv6 src={} dst={} nxt_hdr={} hop_limit={}",
+            self.src_addr,
+            self.dst_addr,
+            self.next_header,
+            self.hop_limit
+        )
+    }
+}
+
 use crate::wire::pretty_print::{PrettyIndent, PrettyPrint};
 
 // TODO: This is very similar to the implementation for IPv4. Make

+ 70 - 3
src/wire/sixlowpan.rs

@@ -405,12 +405,38 @@ pub mod frag {
 
     /// A high-level representation of a 6LoWPAN Fragment header.
     #[derive(Debug, PartialEq, Eq, Clone, Copy)]
-    #[cfg_attr(feature = "defmt", derive(defmt::Format))]
     pub enum Repr {
         FirstFragment { size: u16, tag: u16 },
         Fragment { size: u16, tag: u16, offset: u8 },
     }
 
+    impl core::fmt::Display for Repr {
+        fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+            match self {
+                Repr::FirstFragment { size, tag } => {
+                    write!(f, "FirstFrag size={size} tag={tag}")
+                }
+                Repr::Fragment { size, tag, offset } => {
+                    write!(f, "NthFrag size={size} tag={tag} offset={offset}")
+                }
+            }
+        }
+    }
+
+    #[cfg(feature = "defmt")]
+    impl defmt::Format for Repr {
+        fn format(&self, fmt: defmt::Formatter) {
+            match self {
+                Repr::FirstFragment { size, tag } => {
+                    defmt::write!(fmt, "FirstFrag size={} tag={}", size, tag);
+                }
+                Repr::Fragment { size, tag, offset } => {
+                    defmt::write!(fmt, "NthFrag size={} tag={} offset={}", size, tag, offset);
+                }
+            }
+        }
+    }
+
     impl Repr {
         /// Parse a 6LoWPAN Fragment header.
         pub fn parse<T: AsRef<[u8]>>(packet: &Packet<T>) -> Result<Self> {
@@ -456,12 +482,30 @@ pub mod frag {
 }
 
 #[derive(Debug, PartialEq, Eq, Clone, Copy)]
-#[cfg_attr(feature = "defmt", derive(defmt::Format))]
 pub enum NextHeader {
     Compressed,
     Uncompressed(IpProtocol),
 }
 
+impl core::fmt::Display for NextHeader {
+    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+        match self {
+            NextHeader::Compressed => write!(f, "compressed"),
+            NextHeader::Uncompressed(protocol) => write!(f, "{protocol}"),
+        }
+    }
+}
+
+#[cfg(feature = "defmt")]
+impl defmt::Format for NextHeader {
+    fn format(&self, fmt: defmt::Formatter) {
+        match self {
+            NextHeader::Compressed => defmt::write!(fmt, "compressed"),
+            NextHeader::Uncompressed(protocol) => defmt::write!(fmt, "{}", protocol),
+        }
+    }
+}
+
 pub mod iphc {
     //! Implementation of IP Header Compression from [RFC 6282 § 3.1].
     //! It defines the compression of IPv6 headers.
@@ -1145,7 +1189,6 @@ pub mod iphc {
 
     /// A high-level representation of a 6LoWPAN IPHC header.
     #[derive(Debug, PartialEq, Eq, Clone, Copy)]
-    #[cfg_attr(feature = "defmt", derive(defmt::Format))]
     pub struct Repr {
         pub src_addr: ipv6::Address,
         pub ll_src_addr: Option<LlAddress>,
@@ -1159,6 +1202,30 @@ pub mod iphc {
         pub flow_label: Option<u16>,
     }
 
+    impl core::fmt::Display for Repr {
+        fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+            write!(
+                f,
+                "IPHC src={} dst={} nxt-hdr={} hop-limit={}",
+                self.src_addr, self.dst_addr, self.next_header, self.hop_limit
+            )
+        }
+    }
+
+    #[cfg(feature = "defmt")]
+    impl defmt::Format for Repr {
+        fn format(&self, fmt: defmt::Formatter) {
+            defmt::write!(
+                fmt,
+                "IPHC src={} dst={} nxt-hdr={} hop-limit={}",
+                self.src_addr,
+                self.dst_addr,
+                self.next_header,
+                self.hop_limit
+            );
+        }
+    }
+
     impl Repr {
         /// Parse a 6LoWPAN IPHC header and return a high-level representation.
         ///

+ 30 - 2
src/wire/tcp.rs

@@ -11,7 +11,6 @@ use crate::wire::{IpAddress, IpProtocol};
 /// A sequence number is a monotonically advancing integer modulo 2<sup>32</sup>.
 /// Sequence numbers do not have a discontiguity when compared pairwise across a signed overflow.
 #[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
-#[cfg_attr(feature = "defmt", derive(defmt::Format))]
 pub struct SeqNumber(pub i32);
 
 impl fmt::Display for SeqNumber {
@@ -20,6 +19,13 @@ impl fmt::Display for SeqNumber {
     }
 }
 
+#[cfg(feature = "defmt")]
+impl defmt::Format for SeqNumber {
+    fn format(&self, fmt: defmt::Formatter) {
+        defmt::write!(fmt, "{}", self.0 as u32);
+    }
+}
+
 impl ops::Add<usize> for SeqNumber {
     type Output = SeqNumber;
 
@@ -771,7 +777,6 @@ impl Control {
 
 /// A high-level representation of a Transmission Control Protocol packet.
 #[derive(Debug, PartialEq, Eq, Clone, Copy)]
-#[cfg_attr(feature = "defmt", derive(defmt::Format))]
 pub struct Repr<'a> {
     pub src_port: u16,
     pub dst_port: u16,
@@ -1064,6 +1069,29 @@ impl<'a> fmt::Display for Repr<'a> {
     }
 }
 
+#[cfg(feature = "defmt")]
+impl<'a> defmt::Format for Repr<'a> {
+    fn format(&self, fmt: defmt::Formatter) {
+        defmt::write!(fmt, "TCP src={} dst={}", self.src_port, self.dst_port);
+        match self.control {
+            Control::Syn => defmt::write!(fmt, " syn"),
+            Control::Fin => defmt::write!(fmt, " fin"),
+            Control::Rst => defmt::write!(fmt, " rst"),
+            Control::Psh => defmt::write!(fmt, " psh"),
+            Control::None => (),
+        }
+        defmt::write!(fmt, " seq={}", self.seq_number);
+        if let Some(ack_number) = self.ack_number {
+            defmt::write!(fmt, " ack={}", ack_number);
+        }
+        defmt::write!(fmt, " win={}", self.window_len);
+        defmt::write!(fmt, " len={}", self.payload.len());
+        if let Some(max_seg_size) = self.max_seg_size {
+            defmt::write!(fmt, " mss={}", max_seg_size);
+        }
+    }
+}
+
 use crate::wire::pretty_print::{PrettyIndent, PrettyPrint};
 
 impl<T: AsRef<[u8]>> PrettyPrint for Packet<T> {

+ 21 - 2
src/wire/udp.rs

@@ -8,7 +8,6 @@ use crate::wire::{IpAddress, IpProtocol};
 
 /// A read/write wrapper around an User Datagram Protocol packet buffer.
 #[derive(Debug, PartialEq, Eq, Clone)]
-#[cfg_attr(feature = "defmt", derive(defmt::Format))]
 pub struct Packet<T: AsRef<[u8]>> {
     buffer: T,
 }
@@ -208,7 +207,6 @@ impl<T: AsRef<[u8]>> AsRef<[u8]> for Packet<T> {
 
 /// A high-level representation of an User Datagram Protocol packet.
 #[derive(Debug, PartialEq, Eq, Clone, Copy)]
-#[cfg_attr(feature = "defmt", derive(defmt::Format))]
 pub struct Repr {
     pub src_port: u16,
     pub dst_port: u16,
@@ -305,12 +303,33 @@ impl<'a, T: AsRef<[u8]> + ?Sized> fmt::Display for Packet<&'a T> {
     }
 }
 
+#[cfg(feature = "defmt")]
+impl<'a, T: AsRef<[u8]> + ?Sized> defmt::Format for Packet<&'a T> {
+    fn format(&self, fmt: defmt::Formatter) {
+        // Cannot use Repr::parse because we don't have the IP addresses.
+        defmt::write!(
+            fmt,
+            "UDP src={} dst={} len={}",
+            self.src_port(),
+            self.dst_port(),
+            self.payload().len()
+        );
+    }
+}
+
 impl fmt::Display for Repr {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         write!(f, "UDP src={} dst={}", self.src_port, self.dst_port)
     }
 }
 
+#[cfg(feature = "defmt")]
+impl defmt::Format for Repr {
+    fn format(&self, fmt: defmt::Formatter) {
+        defmt::write!(fmt, "UDP src={} dst={}", self.src_port, self.dst_port);
+    }
+}
+
 use crate::wire::pretty_print::{PrettyIndent, PrettyPrint};
 
 impl<T: AsRef<[u8]>> PrettyPrint for Packet<T> {