lin_ldf/ldf/
mod.rs

1pub mod ldf_comment;
2pub mod ldf_diagnostic_frames;
3pub mod ldf_diagnostic_signals;
4pub mod ldf_frames;
5pub mod ldf_header;
6pub mod ldf_node_attributes;
7pub mod ldf_nodes;
8pub mod ldf_schedule_tables;
9pub mod ldf_signal_encoding_types;
10pub mod ldf_signal_representation;
11pub mod ldf_signals;
12
13use crate::ldf::ldf_comment::skip_whitespace;
14use crate::ldf::ldf_diagnostic_frames::{parse_ldf_diagnostic_frames, LdfDiagnosticFrame};
15use crate::ldf::ldf_diagnostic_signals::{parse_ldf_diagnostic_signals, LdfDiagnosticSignal};
16use crate::ldf::ldf_frames::{parse_ldf_frames, LdfFrame};
17use crate::ldf::ldf_header::{parse_ldf_header, LdfHeader};
18use crate::ldf::ldf_node_attributes::{parse_ldf_node_attributes, LdfNodeAttributes};
19use crate::ldf::ldf_nodes::{parse_ldf_nodes, LdfNodes};
20use crate::ldf::ldf_schedule_tables::{parse_ldf_schedule_tables, LdfScheduleTable};
21use crate::ldf::ldf_signal_encoding_types::{parse_ldf_signal_encoding_types, LdfSignalEncodingType};
22use crate::ldf::ldf_signal_representation::{parse_ldf_signal_representation, LdfSignalRepresentation};
23use crate::ldf::ldf_signals::{parse_ldf_signals, LdfSignal};
24
25pub struct LinLdf {
26    pub header: LdfHeader,
27    pub nodes: LdfNodes,
28    pub signals: Vec<LdfSignal>,
29    pub diagnostic_signals: Vec<LdfDiagnosticSignal>,
30    pub frames: Vec<LdfFrame>,
31    pub diagnostic_frames: Vec<LdfDiagnosticFrame>,
32    pub node_attributes: Vec<LdfNodeAttributes>,
33    pub schedule_tables: Vec<LdfScheduleTable>,
34    pub signal_encoding_types: Vec<LdfSignalEncodingType>,
35    pub signal_representations: Vec<LdfSignalRepresentation>,
36}
37
38impl LinLdf {
39    /// <LIN_description_file> ::=
40    /// ```text
41    /// LIN_description_file ;
42    /// <LIN_protocol_version_def>
43    /// <LIN_language_version_def>
44    /// <LIN_speed_def>
45    /// (<Channel_name_def>)
46    /// <Node_def>
47    /// (<Node_composition_def>)
48    /// <Signal_def>
49    /// (<Diag_signal_def>)
50    /// <Frame_def>
51    /// (<Sporadic_frame_def>)
52    /// (<Event_triggered_frame_def>)
53    /// (<Diag_frame_def>)
54    /// <Node_attributes_def>
55    /// <Schedule_table_def>
56    /// (<Signal_groups_def>)
57    /// (<Signal_encoding_type_def>)
58    /// (<Signal_representation_def>)
59    /// ```
60    pub fn parse(s: &str) -> Result<LinLdf, &'static str> {
61        let (s, _) = skip_whitespace(s).map_err(|_| "Failed to skip whitespace and comments")?;
62        let (s, header) = parse_ldf_header(s).map_err(|_| "Failed to parse header")?;
63        let (s, _) = skip_whitespace(s).map_err(|_| "Failed to skip whitespace and comments")?;
64        let (s, nodes) = parse_ldf_nodes(s).map_err(|_| "Failed to parse Nodes section")?;
65        let (s, _) = skip_whitespace(s).map_err(|_| "Failed to skip whitespace and comments")?;
66        let (s, signals) = parse_ldf_signals(s).map_err(|_| "Failed to parse Signals section (required)")?;
67        let (s, _) = skip_whitespace(s).map_err(|_| "Failed to skip whitespace and comments")?;
68        let (s, diagnostic_signals) =
69            parse_ldf_diagnostic_signals(s).map_err(|_| "Failed to parse Diagnostic_signals section")?;
70        let (s, _) = skip_whitespace(s).map_err(|_| "Failed to skip whitespace and comments")?;
71        let (s, frames) = parse_ldf_frames(s).map_err(|_| "Failed to parse Frames section")?;
72        let (s, _) = skip_whitespace(s).map_err(|_| "Failed to skip whitespace and comments")?;
73        let (s, diagnostic_frames) =
74            parse_ldf_diagnostic_frames(s).map_err(|_| "Failed to parse Diagnostic_frames section")?;
75        let (s, _) = skip_whitespace(s).map_err(|_| "Failed to skip whitespace and comments")?;
76        let (s, node_attributes) =
77            parse_ldf_node_attributes(s).map_err(|_| "Failed to parse Node_attributes section")?;
78        let (s, _) = skip_whitespace(s).map_err(|_| "Failed to skip whitespace and comments")?;
79        let (s, schedule_tables) =
80            parse_ldf_schedule_tables(s).map_err(|_| "Failed to parse Schedule_tables section")?;
81        let (s, _) = skip_whitespace(s).map_err(|_| "Failed to skip whitespace and comments")?;
82        let (s, signal_encoding_types) =
83            parse_ldf_signal_encoding_types(s).map_err(|_| "Failed to parse Signal_encoding_types section")?;
84        let (s, _) = skip_whitespace(s).map_err(|_| "Failed to skip whitespace and comments")?;
85        let (_, signal_representations) =
86            parse_ldf_signal_representation(s).map_err(|_| "Failed to parse Signal_representation section")?;
87
88        Ok(LinLdf {
89            header,
90            nodes,
91            signals,
92            diagnostic_signals,
93            frames,
94            diagnostic_frames,
95            node_attributes,
96            schedule_tables,
97            signal_encoding_types,
98            signal_representations,
99        })
100    }
101}
102
103#[cfg(test)]
104mod tests {
105    use crate::ldf::ldf_signals::LdfSignalInitValue;
106
107    use super::*;
108
109    #[test]
110    fn test_parse() {
111        let input = r#"
112            /* MY BLOCK COMMENT */
113            
114            LIN_description_file ; 
115            LIN_protocol_version = "2.1" ; 
116            LIN_language_version = "2.1" ; 
117            LIN_speed = 19.2 kbps ;
118            
119            Nodes {
120                Master: Master, 5 ms, 0.1 ms ;
121                Slaves: Slave1, Slave2, Slave3 ;
122            }
123
124            // MY LINE COMMENT
125
126            Signals {
127                Signal1: 10, 0, Master, Slave1 , Slave2 ;
128                Signal2: 10, 0, Master, Slave1 ;
129                Signal3: 10, 0, Master, Slave1 ;
130                Signal4: 10, 0, Slave1, Master ;
131                Signal5: 2, 0, Slave1, Master ;
132                Signal6: 1, 0, Slave1, Master ;
133            }
134
135            Diagnostic_signals {
136                MasterReqB0: 8, 0 ;   /* MID SECTION COMMENT */
137                MasterReqB1: 8, 0 ;
138                MasterReqB2: 8, 0 ;
139                MasterReqB3: 8, 0 ;
140                MasterReqB4: 8, 0 ;
141                MasterReqB5: 8, 0 ;   /* MID SECTION COMMENT */
142            }
143
144            Frames {
145                Frame1: 0, Master, 8 {
146                    Signal1, 0 ;      /* MID SECTION COMMENT */
147                    Signal2, 10 ;
148                }
149                Frame2: 0x16, Slave1, 8 {
150                    Signal3, 0 ;
151                    Signal4, 10 ;
152                }
153            }
154
155            Diagnostic_frames {
156                MasterReq: 0x3C {
157                    MasterReqB0, 0 ;
158                    MasterReqB1, 8 ;
159                    MasterReqB2, 16 ;
160                    MasterReqB3, 24 ;
161                    MasterReqB4, 32 ;
162                    MasterReqB5, 40 ;
163                    MasterReqB6, 48 ;
164                    MasterReqB7, 56 ;
165                }
166                SlaveResp: 0x3D {
167                    SlaveRespB0, 0 ;
168                    SlaveRespB1, 8 ;
169                    SlaveRespB2, 16 ;
170                    SlaveRespB3, 24 ;
171                    SlaveRespB4, 32 ;
172                    SlaveRespB5, 40 ;
173                    SlaveRespB6, 48 ;
174                    SlaveRespB7, 56 ;
175                }
176            }
177
178            Node_attributes {
179                Slave1{
180                    LIN_protocol = "2.1" ;
181                    configured_NAD = 0xB ;
182                    initial_NAD = 0xB ;
183                    product_id = 0x123, 0x4567, 8 ;
184                    response_error = Signal1 ;
185                    P2_min = 100 ms ;
186                    ST_min = 0 ms ;
187                    N_As_timeout = 1000 ms ;
188                    N_Cr_timeout = 1000 ms ;
189                    configurable_frames {
190                        Frame1 ;
191                        Frame2 ;  
192                    }
193                }
194                Slave2{
195                    LIN_protocol = "2.1" ;
196                    configured_NAD = 0xC ;
197                    initial_NAD = 0xC ;
198                    product_id = 0x124, 0x4568, 0x66 ;
199                    response_error = Signal2 ;
200                    P2_min = 100 ms ;
201                    ST_min = 0 ms ;
202                    N_As_timeout = 1000 ms ;
203                    N_Cr_timeout = 1000 ms ;
204                    configurable_frames {
205                        Frame1 ;
206                        Frame2 ;
207                    }
208                }
209            }
210
211            Schedule_tables {
212                AllFrames {
213                    Frame1 delay 10 ms ;
214                    Frame2 delay 10 ms ;
215                }
216            }
217
218            Signal_encoding_types {
219                ENC_BOOL {
220                    logical_value, 0, "FALSE" ;
221                    logical_value, 1, "TRUE" ;
222                }
223                ENC_TEMP {
224                    physical_value, 0, 1023, 0.2, -40, "degC" ;
225                }
226                ENC_RPM {
227                    physical_value, 0, 1023, 10, 0, "rpm" ;
228                }
229            }
230
231            Signal_representation {
232                ENC_BOOL: Signal1, Signal2 ;
233                ENC_TEMP: Signal3, Signal4 ;
234                ENC_RPM: Signal5, Signal6 ;
235            }
236        "#;
237
238        let ldf = LinLdf::parse(input).unwrap();
239
240        // Header
241        assert_eq!(ldf.header.lin_protocol_version, "2.1");
242        assert_eq!(ldf.header.lin_language_version, "2.1");
243        assert_eq!(ldf.header.lin_speed, 19200);
244
245        // Nodes
246        assert_eq!(ldf.nodes.master.name, "Master");
247        assert_eq!(ldf.nodes.master.time_base, "5 ms");
248        assert_eq!(ldf.nodes.master.jitter, "0.1 ms");
249        assert_eq!(ldf.nodes.slaves.len(), 3);
250        assert_eq!(ldf.nodes.slaves[0].name, "Slave1");
251        assert_eq!(ldf.nodes.slaves[1].name, "Slave2");
252        assert_eq!(ldf.nodes.slaves[2].name, "Slave3");
253
254        // Signals
255        assert_eq!(ldf.signals.len(), 6);
256        assert_eq!(ldf.signals[0].name, "Signal1");
257        assert_eq!(ldf.signals[0].signal_size, 10);
258        assert_eq!(ldf.signals[0].init_value, LdfSignalInitValue::Scalar(0));
259        assert_eq!(ldf.signals[0].published_by, "Master");
260        assert_eq!(ldf.signals[0].subscribed_by[0], "Slave1");
261        assert_eq!(ldf.signals[5].name, "Signal6");
262        assert_eq!(ldf.signals[5].signal_size, 1);
263        assert_eq!(ldf.signals[5].init_value, LdfSignalInitValue::Scalar(0));
264        assert_eq!(ldf.signals[5].published_by, "Slave1");
265        assert_eq!(ldf.signals[5].subscribed_by[0], "Master");
266
267        // Diagnostic signals
268        assert_eq!(ldf.diagnostic_signals.len(), 6);
269        assert_eq!(ldf.diagnostic_signals[0].name, "MasterReqB0");
270        assert_eq!(ldf.diagnostic_signals[0].length, 8);
271        assert_eq!(ldf.diagnostic_signals[0].init_value, 0);
272        assert_eq!(ldf.diagnostic_signals[5].name, "MasterReqB5");
273        assert_eq!(ldf.diagnostic_signals[5].length, 8);
274        assert_eq!(ldf.diagnostic_signals[5].init_value, 0);
275
276        // Frames
277        assert_eq!(ldf.frames.len(), 2);
278        assert_eq!(ldf.frames[0].frame_name, "Frame1");
279        assert_eq!(ldf.frames[0].frame_id, 0);
280        assert_eq!(ldf.frames[0].published_by, "Master");
281        assert_eq!(ldf.frames[0].frame_size, 8);
282        assert_eq!(ldf.frames[0].signals.len(), 2);
283        assert_eq!(ldf.frames[0].signals[0].signal_name, "Signal1");
284        assert_eq!(ldf.frames[0].signals[0].start_bit, 0);
285        assert_eq!(ldf.frames[0].signals[1].signal_name, "Signal2");
286        assert_eq!(ldf.frames[0].signals[1].start_bit, 10);
287        assert_eq!(ldf.frames[1].frame_name, "Frame2");
288        assert_eq!(ldf.frames[1].frame_id, 0x16);
289        assert_eq!(ldf.frames[1].published_by, "Slave1");
290        assert_eq!(ldf.frames[1].frame_size, 8);
291        assert_eq!(ldf.frames[1].signals.len(), 2);
292        assert_eq!(ldf.frames[1].signals[0].signal_name, "Signal3");
293        assert_eq!(ldf.frames[1].signals[0].start_bit, 0);
294        assert_eq!(ldf.frames[1].signals[1].signal_name, "Signal4");
295        assert_eq!(ldf.frames[1].signals[1].start_bit, 10);
296
297        // Diagnostic frames
298        assert_eq!(ldf.diagnostic_frames.len(), 2);
299        assert_eq!(ldf.diagnostic_frames[0].frame_name, "MasterReq");
300        assert_eq!(ldf.diagnostic_frames[0].frame_id, 0x3C);
301        assert_eq!(ldf.diagnostic_frames[0].signals.len(), 8);
302        assert_eq!(ldf.diagnostic_frames[0].signals[0].signal_name, "MasterReqB0");
303        assert_eq!(ldf.diagnostic_frames[0].signals[0].start_bit, 0);
304        assert_eq!(ldf.diagnostic_frames[0].signals[7].signal_name, "MasterReqB7");
305        assert_eq!(ldf.diagnostic_frames[0].signals[7].start_bit, 56);
306        assert_eq!(ldf.diagnostic_frames[1].frame_name, "SlaveResp");
307        assert_eq!(ldf.diagnostic_frames[1].frame_id, 0x3D);
308        assert_eq!(ldf.diagnostic_frames[1].signals.len(), 8);
309        assert_eq!(ldf.diagnostic_frames[1].signals[0].signal_name, "SlaveRespB0");
310        assert_eq!(ldf.diagnostic_frames[1].signals[0].start_bit, 0);
311        assert_eq!(ldf.diagnostic_frames[1].signals[7].signal_name, "SlaveRespB7");
312        assert_eq!(ldf.diagnostic_frames[1].signals[7].start_bit, 56);
313
314        // Node attributes
315        assert_eq!(ldf.node_attributes.len(), 2);
316        assert_eq!(ldf.node_attributes[0].node_name, "Slave1");
317        assert_eq!(ldf.node_attributes[0].lin_protocol, "2.1");
318        assert_eq!(ldf.node_attributes[0].configured_nad, 0xB);
319        assert_eq!(ldf.node_attributes[0].initial_nad, 0xB);
320        assert_eq!(ldf.node_attributes[0].supplier_id, 0x123);
321        assert_eq!(ldf.node_attributes[0].function_id, 0x4567);
322        assert_eq!(ldf.node_attributes[0].variant, 8);
323        assert_eq!(ldf.node_attributes[0].response_error, "Signal1");
324        assert_eq!(ldf.node_attributes[0].p2_min, "100 ms");
325        assert_eq!(ldf.node_attributes[0].st_min, "0 ms");
326        assert_eq!(ldf.node_attributes[0].n_as_timeout, "1000 ms");
327        assert_eq!(ldf.node_attributes[0].n_cr_timeout, "1000 ms");
328        assert_eq!(ldf.node_attributes[0].configurable_frames.len(), 2);
329        assert_eq!(ldf.node_attributes[0].configurable_frames[0], "Frame1");
330        assert_eq!(ldf.node_attributes[0].configurable_frames[1], "Frame2");
331        assert_eq!(ldf.node_attributes[1].node_name, "Slave2");
332        assert_eq!(ldf.node_attributes[1].lin_protocol, "2.1");
333        assert_eq!(ldf.node_attributes[1].configured_nad, 0xC);
334        assert_eq!(ldf.node_attributes[1].initial_nad, 0xC);
335        assert_eq!(ldf.node_attributes[1].supplier_id, 0x124);
336        assert_eq!(ldf.node_attributes[1].function_id, 0x4568);
337        assert_eq!(ldf.node_attributes[1].variant, 0x66);
338        assert_eq!(ldf.node_attributes[1].response_error, "Signal2");
339        assert_eq!(ldf.node_attributes[1].p2_min, "100 ms");
340        assert_eq!(ldf.node_attributes[1].st_min, "0 ms");
341        assert_eq!(ldf.node_attributes[1].n_as_timeout, "1000 ms");
342        assert_eq!(ldf.node_attributes[1].n_cr_timeout, "1000 ms");
343        assert_eq!(ldf.node_attributes[1].configurable_frames.len(), 2);
344        assert_eq!(ldf.node_attributes[1].configurable_frames[0], "Frame1");
345        assert_eq!(ldf.node_attributes[1].configurable_frames[1], "Frame2");
346
347        // Schedule tables
348        assert_eq!(ldf.schedule_tables.len(), 1);
349        assert_eq!(ldf.schedule_tables[0].schedule_table_name, "AllFrames");
350        assert_eq!(ldf.schedule_tables[0].frame_delays.len(), 2);
351        assert_eq!(ldf.schedule_tables[0].frame_delays[0].frame_name, "Frame1");
352        assert_eq!(ldf.schedule_tables[0].frame_delays[0].frame_time, 10.0);
353        assert_eq!(ldf.schedule_tables[0].frame_delays[1].frame_name, "Frame2");
354        assert_eq!(ldf.schedule_tables[0].frame_delays[1].frame_time, 10.0);
355
356        // Signal encoding types
357        assert_eq!(ldf.signal_encoding_types.len(), 3);
358        assert_eq!(ldf.signal_encoding_types[0].encoding_type_name, "ENC_BOOL");
359        assert_eq!(ldf.signal_encoding_types[0].encoding_type_values.len(), 2);
360
361        // Signal representations
362        assert_eq!(ldf.signal_representations.len(), 3);
363        assert_eq!(ldf.signal_representations[0].encoding_type_name, "ENC_BOOL");
364        assert_eq!(ldf.signal_representations[0].signal_names.len(), 2);
365        assert_eq!(ldf.signal_representations[0].signal_names[0], "Signal1");
366        assert_eq!(ldf.signal_representations[0].signal_names[1], "Signal2");
367    }
368}