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