rtcm_rs/msg/
message.rs

1use crate::crc_any::CRC;
2use crate::df::bit_value::U16;
3use crate::df::{assembler::Assembler, parser::Parser};
4use crate::message_frame::MessageFrame;
5use crate::rtcm_error::RtcmError;
6#[cfg(feature = "serde")]
7use sd::{Deserialize, Serialize};
8
9macro_rules! message {
10    (
11        $( $feature:literal: $enum_v:ident($msg_id:ident) = $enum_pv:literal ),*
12    ) => {
13        $(
14            #[cfg(feature = $feature)]
15            use $crate::msg::$msg_id::$msg_id;
16        )*
17        #[non_exhaustive]
18        #[repr(u16)]
19        #[cfg_attr(feature="serde",derive(Serialize,Deserialize),serde(crate = "sd"))]
20        #[derive(Debug,PartialEq)]
21        pub enum Message {
22            Empty = 5000,
23            Corrupt = 6000,
24            MsgNotSupported(MsgNotSupportedT) = 7000,
25            $(
26                #[cfg(feature = $feature)]
27                $enum_v($msg_id::DataType) = $enum_pv
28            ),*
29        }
30        impl Message {
31            pub fn from_message_frame(message_frame: &MessageFrame) -> Self {
32                let message_number = if let Some(message_number) = message_frame.message_number() {
33                    message_number
34                } else {
35                    return Message::Empty;
36                };
37                let mut parser = Parser::new(message_frame.data(), 12);
38                match message_number {
39                    $(
40                        #[cfg(feature = $feature)]
41                        $enum_pv => if let Ok(value) = $msg_id::decode(&mut parser) {
42                            Message::$enum_v(value)
43                        } else {
44                            Message::Corrupt
45                        },
46                    )*
47                    _ => Message::MsgNotSupported(MsgNotSupportedT {
48                        message_number
49                    }),
50                }
51            }
52            pub fn number(&self) -> Option<u16> {
53                match self {
54                    $(
55                        #[cfg(feature = $feature)]
56                        Message::$enum_v(_) => {
57                            Some($enum_pv)
58                        }
59                    )*
60                    _ => {
61                        None
62                    },
63                }
64            }
65        }
66        #[cfg_attr(feature="serde",derive(Serialize,Deserialize),serde(crate = "sd"))]
67        #[derive(Debug,PartialEq)]
68        pub struct MsgNotSupportedT {
69            pub message_number:u16,
70        }
71
72        #[cfg(feature = "test_gen")]
73        impl $crate::source_repr::SourceRepr for Message {
74            fn to_source(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
75                use core::fmt::Write;
76                match self {
77                    Message::Empty => {
78                        f.write_str("Message::Empty")
79                    },
80                    Message::Corrupt => {
81                        f.write_str("Message::Corrupt")
82                    },
83                    $(
84                        #[cfg(feature = $feature)]
85                        Message::$enum_v(msgt) => {
86                            write!(f, "Message::{}(", stringify!($enum_v))?;
87                            msgt.to_source(f)?;
88                            f.write_char(')')
89                        },
90                    )*
91                    Message::MsgNotSupported(msgt) => {
92                        write!(f, "Message::MsgNotSupported(MsgNotSupportedT{{ message_number:{} }})", msgt.message_number)
93                    },
94                }
95            }
96        }
97
98        pub struct MessageBuilder {
99            data:[u8;1029],
100            has_run:bool,
101        }
102        #[cfg(feature = "test_gen")]
103        use $crate::val_gen::ValGen;
104
105        impl MessageBuilder {
106            pub fn new() -> Self {
107                let mut ret = MessageBuilder {
108                    data: [0;1029],
109                    has_run:false,
110                };
111                ret.data[0] = 0xd3;
112                ret
113            }
114            pub fn build_message(&mut self, message:&Message) -> Result<&[u8],RtcmError> {
115                if self.has_run {
116                    self.clear_data();
117                }
118                self.has_run = true;
119                let mut asm = Assembler::new(&mut self.data[3..1026], 0);
120                //encode message number into message
121                if let Some(number) = message.number() {
122                    asm.put::<U16>(number,12)?;
123                } else {
124                    return Err(RtcmError::EncodingNotSupported);
125                }
126
127                match message {
128                    $(
129                        #[cfg(feature = $feature)]
130                        Message::$enum_v(dt) => {
131                            $msg_id::encode(&mut asm,&dt)?;
132                        }
133                    )*
134                    _ => {
135                        unreachable!();
136                    },
137                }
138                //encode data length
139                let data_len = (asm.offset() - 1)/8 + 1;
140                self.data[1] = (data_len >> 8) as u8;
141                self.data[2] = (data_len & 0xff) as u8;
142                //encode crc
143                let mut crc = CRC::crc24lte_a();
144                crc.digest(&self.data[..data_len+3]);
145                let crc = crc.get_crc();
146                self.data[data_len+3] = ((crc >> 16) & 0xff) as u8;
147                self.data[data_len+4] = ((crc >> 8) & 0xff) as u8;
148                self.data[data_len+5] = (crc & 0xff) as u8;
149
150                Ok(&self.data[..data_len+6])
151            }
152
153            #[cfg(feature = "test_gen")]
154            pub fn build_generated_message<FR,LR,RR>(&mut self, val_gen:&mut ValGen<FR,LR,RR>, message_number:u16) -> Result<&[u8],RtcmError>
155            where FR:rand::Rng, LR:rand::Rng, RR:rand::Rng {
156                if self.has_run {
157                    self.clear_data();
158                }
159                self.has_run = true;
160                let mut asm = Assembler::new(&mut self.data[3..1026], 0);
161                asm.put::<U16>(message_number,12)?;
162
163                match message_number {
164                    $(
165                        #[cfg(feature = $feature)]
166                        $enum_pv => {
167                            $msg_id::generate(&mut asm, val_gen)?;
168                        }
169                    )*
170                    _ => return Err(RtcmError::EncodingNotSupported)
171                }
172                //encode data length
173                let data_len = (asm.offset() - 1)/8 + 1;
174                self.data[1] = (data_len >> 8) as u8;
175                self.data[2] = (data_len & 0xff) as u8;
176                //encode crc
177                let mut crc = CRC::crc24lte_a();
178                crc.digest(&self.data[..data_len+3]);
179                let crc = crc.get_crc();
180                self.data[data_len+3] = ((crc >> 16) & 0xff) as u8;
181                self.data[data_len+4] = ((crc >> 8) & 0xff) as u8;
182                self.data[data_len+5] = (crc & 0xff) as u8;
183
184                Ok(&self.data[..data_len+6])
185            }
186            fn clear_data(&mut self) {
187                for d in self.data[1..].iter_mut() {
188                    *d = 0;
189                }
190            }
191        }
192    };
193}
194
195message!(
196    "msg1001": Msg1001(msg1001) = 1001,
197    "msg1002": Msg1002(msg1002) = 1002,
198    "msg1003": Msg1003(msg1003) = 1003,
199    "msg1004": Msg1004(msg1004) = 1004,
200    "msg1005": Msg1005(msg1005) = 1005,
201    "msg1006": Msg1006(msg1006) = 1006,
202    "msg1007": Msg1007(msg1007) = 1007,
203    "msg1008": Msg1008(msg1008) = 1008,
204    "msg1009": Msg1009(msg1009) = 1009,
205    "msg1010": Msg1010(msg1010) = 1010,
206    "msg1011": Msg1011(msg1011) = 1011,
207    "msg1012": Msg1012(msg1012) = 1012,
208    "msg1013": Msg1013(msg1013) = 1013,
209    "msg1014": Msg1014(msg1014) = 1014,
210    "msg1015": Msg1015(msg1015) = 1015,
211    "msg1016": Msg1016(msg1016) = 1016,
212    "msg1017": Msg1017(msg1017) = 1017,
213    "msg1019": Msg1019(msg1019) = 1019,
214    "msg1020": Msg1020(msg1020) = 1020,
215    "msg1021": Msg1021(msg1021) = 1021,
216    "msg1022": Msg1022(msg1022) = 1022,
217    "msg1023": Msg1023(msg1023) = 1023,
218    "msg1024": Msg1024(msg1024) = 1024,
219    "msg1025": Msg1025(msg1025) = 1025,
220    "msg1026": Msg1026(msg1026) = 1026,
221    "msg1027": Msg1027(msg1027) = 1027,
222    "msg1029": Msg1029(msg1029) = 1029,
223    "msg1030": Msg1030(msg1030) = 1030,
224    "msg1031": Msg1031(msg1031) = 1031,
225    "msg1032": Msg1032(msg1032) = 1032,
226    "msg1033": Msg1033(msg1033) = 1033,
227    "msg1034": Msg1034(msg1034) = 1034,
228    "msg1035": Msg1035(msg1035) = 1035,
229    "msg1037": Msg1037(msg1037) = 1037,
230    "msg1038": Msg1038(msg1038) = 1038,
231    "msg1039": Msg1039(msg1039) = 1039,
232    "msg1041": Msg1041(msg1041) = 1041,
233    "msg1042": Msg1042(msg1042) = 1042,
234    "msg1044": Msg1044(msg1044) = 1044,
235    "msg1045": Msg1045(msg1045) = 1045,
236    "msg1046": Msg1046(msg1046) = 1046,
237    "msg1057": Msg1057(msg1057) = 1057,
238    "msg1058": Msg1058(msg1058) = 1058,
239    "msg1059": Msg1059(msg1059) = 1059,
240    "msg1060": Msg1060(msg1060) = 1060,
241    "msg1061": Msg1061(msg1061) = 1061,
242    "msg1062": Msg1062(msg1062) = 1062,
243    "msg1063": Msg1063(msg1063) = 1063,
244    "msg1064": Msg1064(msg1064) = 1064,
245    "msg1065": Msg1065(msg1065) = 1065,
246    "msg1066": Msg1066(msg1066) = 1066,
247    "msg1067": Msg1067(msg1067) = 1067,
248    "msg1068": Msg1068(msg1068) = 1068,
249    "msg1071": Msg1071(msg1071) = 1071,
250    "msg1072": Msg1072(msg1072) = 1072,
251    "msg1073": Msg1073(msg1073) = 1073,
252    "msg1074": Msg1074(msg1074) = 1074,
253    "msg1075": Msg1075(msg1075) = 1075,
254    "msg1076": Msg1076(msg1076) = 1076,
255    "msg1077": Msg1077(msg1077) = 1077,
256    "msg1081": Msg1081(msg1081) = 1081,
257    "msg1082": Msg1082(msg1082) = 1082,
258    "msg1083": Msg1083(msg1083) = 1083,
259    "msg1084": Msg1084(msg1084) = 1084,
260    "msg1085": Msg1085(msg1085) = 1085,
261    "msg1086": Msg1086(msg1086) = 1086,
262    "msg1087": Msg1087(msg1087) = 1087,
263    "msg1091": Msg1091(msg1091) = 1091,
264    "msg1092": Msg1092(msg1092) = 1092,
265    "msg1093": Msg1093(msg1093) = 1093,
266    "msg1094": Msg1094(msg1094) = 1094,
267    "msg1095": Msg1095(msg1095) = 1095,
268    "msg1096": Msg1096(msg1096) = 1096,
269    "msg1097": Msg1097(msg1097) = 1097,
270    "msg1101": Msg1101(msg1101) = 1101,
271    "msg1102": Msg1102(msg1102) = 1102,
272    "msg1103": Msg1103(msg1103) = 1103,
273    "msg1104": Msg1104(msg1104) = 1104,
274    "msg1105": Msg1105(msg1105) = 1105,
275    "msg1106": Msg1106(msg1106) = 1106,
276    "msg1107": Msg1107(msg1107) = 1107,
277    "msg1111": Msg1111(msg1111) = 1111,
278    "msg1112": Msg1112(msg1112) = 1112,
279    "msg1113": Msg1113(msg1113) = 1113,
280    "msg1114": Msg1114(msg1114) = 1114,
281    "msg1115": Msg1115(msg1115) = 1115,
282    "msg1116": Msg1116(msg1116) = 1116,
283    "msg1117": Msg1117(msg1117) = 1117,
284    "msg1121": Msg1121(msg1121) = 1121,
285    "msg1122": Msg1122(msg1122) = 1122,
286    "msg1123": Msg1123(msg1123) = 1123,
287    "msg1124": Msg1124(msg1124) = 1124,
288    "msg1125": Msg1125(msg1125) = 1125,
289    "msg1126": Msg1126(msg1126) = 1126,
290    "msg1127": Msg1127(msg1127) = 1127,
291    "msg1131": Msg1131(msg1131) = 1131,
292    "msg1132": Msg1132(msg1132) = 1132,
293    "msg1133": Msg1133(msg1133) = 1133,
294    "msg1134": Msg1134(msg1134) = 1134,
295    "msg1135": Msg1135(msg1135) = 1135,
296    "msg1136": Msg1136(msg1136) = 1136,
297    "msg1137": Msg1137(msg1137) = 1137,
298    "msg1230": Msg1230(msg1230) = 1230,
299    "msg1300": Msg1300(msg1300) = 1300,
300    "msg1301": Msg1301(msg1301) = 1301,
301    "msg1302": Msg1302(msg1302) = 1302,
302    "msg1303": Msg1303(msg1303) = 1303,
303    "msg1304": Msg1304(msg1304) = 1304
304);