stackforge_core/layer/dot15d4/
crc.rs1pub fn crc_ccitt_kermit(data: &[u8]) -> u16 {
15 let mut crc: u16 = 0;
16 for &byte in data {
17 let c = byte as u16;
18 let q = (crc ^ c) & 0x0F;
20 crc = (crc >> 4) ^ (q * 4225);
21 let q = (crc ^ (c >> 4)) & 0x0F;
23 crc = (crc >> 4) ^ (q * 4225);
24 }
25 crc
26}
27
28pub fn compute_fcs(data: &[u8]) -> [u8; 2] {
30 crc_ccitt_kermit(data).to_le_bytes()
31}
32
33pub fn verify_fcs(data: &[u8], expected_fcs: u16) -> bool {
38 crc_ccitt_kermit(data) == expected_fcs
39}
40
41#[cfg(test)]
42mod tests {
43 use super::*;
44
45 #[test]
46 fn test_crc_empty() {
47 assert_eq!(crc_ccitt_kermit(&[]), 0x0000);
48 }
49
50 #[test]
51 fn test_crc_known_value() {
52 let data = b"123456789";
54 assert_eq!(crc_ccitt_kermit(data), 0x2189);
55 }
56
57 #[test]
58 fn test_compute_fcs_le_bytes() {
59 let data = b"123456789";
60 let fcs = compute_fcs(data);
61 assert_eq!(fcs, [0x89, 0x21]);
63 }
64
65 #[test]
66 fn test_verify_fcs() {
67 let data = b"123456789";
68 assert!(verify_fcs(data, 0x2189));
69 assert!(!verify_fcs(data, 0x0000));
70 }
71
72 #[test]
73 fn test_crc_single_byte() {
74 let crc = crc_ccitt_kermit(&[0x00]);
76 assert_eq!(crc, 0x0000);
77 }
78
79 #[test]
80 fn test_crc_802154_beacon_frame() {
81 let data = [0x00, 0x00, 0x01];
84 let crc = crc_ccitt_kermit(&data);
85 let fcs_bytes = compute_fcs(&data);
86 assert!(verify_fcs(&data, crc));
88 assert_eq!(fcs_bytes, crc.to_le_bytes());
89 }
90
91 #[test]
92 fn test_crc_deterministic() {
93 let data = [0x41, 0x88, 0x05, 0xFF, 0xFF, 0x34, 0x12];
94 let crc1 = crc_ccitt_kermit(&data);
95 let crc2 = crc_ccitt_kermit(&data);
96 assert_eq!(crc1, crc2);
97 }
98
99 #[test]
100 fn test_verify_fcs_wrong_data() {
101 let data1 = [0x01, 0x02, 0x03];
102 let crc = crc_ccitt_kermit(&data1);
103 let data2 = [0x01, 0x02, 0x04]; assert!(!verify_fcs(&data2, crc));
105 }
106}