n2k_base/n2k/header/
mod.rs1#[derive(Debug, PartialEq, Clone, Copy)]
3pub struct N2kHeader(u32);
4
5impl N2kHeader {
6 pub fn new(priority: u8, source: u8, destination: u8, pgn: u32) -> N2kHeader {
8 let mut id = (priority as u32) << 26 | (pgn << 8) | source as u32;
10
11 let pdu_format = (pgn >> 8) as u8;
12
13 if pdu_format < 240 {
14 id = id | ((destination as u32) << 8);
16 }
17 N2kHeader(id)
18 }
19
20 pub fn from_raw(raw_id: u32) -> N2kHeader {
21 N2kHeader(raw_id)
22 }
23}
24
25impl Into<u32> for N2kHeader {
27 fn into(self) -> u32 {
28 self.0
29 }
30}
31
32pub trait N2kHeaderDecoder {
35 fn get_pgn(&self) -> u32;
36 fn get_source(&self) -> u8;
37 fn get_destination(&self) -> u8;
38 fn get_priority(&self) -> u8;
39}
40
41impl N2kHeaderDecoder for N2kHeader {
42 fn get_pgn(&self) -> u32 {
43 let pf = get_pdu_format(&self.0);
44 let pdu_specific = get_pdu_specific(&self.0);
45 let dp = get_data_page(&self.0);
46
47 if pf < 240 {
48 (dp as u32) << 16 | (pf as u32) << 8
49 } else {
50 (dp as u32) << 16 | (pf as u32) << 8 | pdu_specific as u32
51 }
52 }
53
54 fn get_source(&self) -> u8 {
55 self.0 as u8
56 }
57
58 fn get_destination(&self) -> u8 {
59 let pf = get_pdu_format(&self.0);
60 let ps = get_pdu_specific(&self.0);
61 if pf < 240 {
62 ps
63 } else {
64 0xFF
65 }
66 }
67
68 fn get_priority(&self) -> u8 {
69 ((self.0 >> 26) & 0x7) as u8
70 }
71}
72
73
74fn get_pdu_specific(id: &u32) -> u8 {
75 (id >> 8) as u8
76}
77
78fn get_pdu_format(id: &u32) -> u8 {
79 (id >> 16) as u8
80}
81
82fn get_data_page(id: &u32) -> u8 {
83 ((id >> 24) & 1 as u32) as u8
84}
85
86#[cfg(test)]
87mod tests {
88 use super::*;
89
90 #[test]
91 fn read_iso_address_claim_header() {
92 let id = N2kHeader(0x18EEFF0A);
93 assert_eq!(id.get_source(), 10);
94 assert_eq!(id.get_pgn(), 60928);
95 assert_eq!(id.get_destination(), 255);
96 assert_eq!(id.get_priority(), 6);
97 }
98
99 #[test]
100 fn read_wind_data_header() {
101 let id = N2kHeader(0x09FD020A);
102
103 assert_eq!(id.get_source(), 10);
104 assert_eq!(id.get_pgn(), 130306);
105 assert_eq!(id.get_destination(), 255);
106 assert_eq!(id.get_priority(), 2);
107 }
108
109 #[test]
110 fn create_iso_address_claim_header() {
111 let id = N2kHeader::new(
112 6,
113 10,
114 255,
115 60928,
116 );
117
118 assert_eq!(id, N2kHeader(0x18EEFF0A));
119 assert_eq!(id.get_source(), 10);
120 assert_eq!(id.get_pgn(), 60928);
121 assert_eq!(id.get_destination(), 255);
122 assert_eq!(id.get_priority(), 6);
123 }
124
125 #[test]
126 fn create_wind_data_header() {
127 let id = N2kHeader::new(
128 2,
129 10,
130 255,
131 130306,
132 );
133 assert_eq!(id, N2kHeader(0x09FD020A));
134 assert_eq!(id.get_source(), 10);
135 assert_eq!(id.get_pgn(), 130306);
136 assert_eq!(id.get_destination(), 255);
137 assert_eq!(id.get_priority(), 2);
138 }
139}