leodos_protocols/transport/cfdp/
checksum.rs1pub trait CfdpChecksum: Send {
3 fn update(&mut self, data: &[u8]);
5
6 fn finalize(self) -> u32;
8}
9
10pub mod modular {
12 use heapless::Vec;
13
14 use crate::transport::cfdp::checksum::CfdpChecksum;
15
16 pub struct ModularChecksum {
18 sum: u32,
20 pending: Vec<u8, 4>,
22 }
23
24 impl ModularChecksum {
25 pub fn new() -> Self {
27 Self {
28 sum: 0,
29 pending: Vec::new(),
30 }
31 }
32 }
33
34 impl CfdpChecksum for ModularChecksum {
35 fn update(&mut self, data: &[u8]) {
36 let mut cursor = 0;
37
38 while !self.pending.is_full() && cursor < data.len() {
40 let _ = self.pending.push(data[cursor]);
41 cursor += 1;
42 }
43
44 if self.pending.is_full() {
46 let word = u32::from_be_bytes(self.pending.as_slice().try_into().unwrap());
47 self.sum = self.sum.wrapping_add(word);
48 self.pending.clear();
49 }
50
51 let remaining = &data[cursor..];
53 let mut chunks = remaining.chunks_exact(4);
54 for chunk in chunks.by_ref() {
55 let word = u32::from_be_bytes(chunk.try_into().unwrap());
56 self.sum = self.sum.wrapping_add(word);
57 }
58
59 for b in chunks.remainder() {
61 let _ = self.pending.push(*b);
62 }
63 }
64
65 fn finalize(self) -> u32 {
66 let mut final_sum = self.sum;
67 if !self.pending.is_empty() {
68 let mut padded = [0u8; 4];
69 padded[..self.pending.len()].copy_from_slice(&self.pending);
70 let word = u32::from_be_bytes(padded);
71 final_sum = final_sum.wrapping_add(word);
72 }
73 final_sum
74 }
75 }
76}
77
78pub mod crc {
80 use crc::CRC_32_ISCSI;
81 use crc::CRC_32_ISO_HDLC;
82 use crc::Crc;
83 use crc::Digest;
84
85 use crate::transport::cfdp::checksum::CfdpChecksum;
86
87 static CRC_CASTAGNOLI: Crc<u32> = Crc::<u32>::new(&CRC_32_ISCSI);
88 static CRC_IEEE: Crc<u32> = Crc::<u32>::new(&CRC_32_ISO_HDLC);
89
90 pub struct CrcChecksum {
92 digest: Digest<'static, u32>,
94 }
95
96 impl CrcChecksum {
97 pub fn crc32c() -> Self {
99 Self {
100 digest: CRC_CASTAGNOLI.digest(),
101 }
102 }
103
104 pub fn ieee() -> Self {
106 Self {
107 digest: CRC_IEEE.digest(),
108 }
109 }
110 }
111 impl CfdpChecksum for CrcChecksum {
112 fn update(&mut self, data: &[u8]) {
113 self.digest.update(data);
114 }
115
116 fn finalize(self) -> u32 {
117 self.digest.finalize()
118 }
119 }
120}
121
122pub mod null {
124 use crate::transport::cfdp::checksum::CfdpChecksum;
125
126 pub struct NullChecksum;
128
129 impl CfdpChecksum for NullChecksum {
130 fn update(&mut self, _data: &[u8]) {}
131 fn finalize(self) -> u32 {
132 0
133 }
134 }
135}