autosar_data_abstraction/communication/frame/
lin.rs

1use crate::communication::{
2    AbstractFrame, AbstractFrameTriggering, AbstractPdu, Frame, FrameTriggering, PduToFrameMapping,
3};
4use crate::{
5    AbstractionElement, AutosarAbstractionError, ByteOrder, IdentifiableAbstractionElement, abstraction_element,
6};
7use autosar_data::{Element, ElementName};
8
9//##################################################################
10
11/// A frame on a LIN bus
12#[derive(Debug, Clone, PartialEq, Eq, Hash)]
13pub struct LinEventTriggeredFrame(Element);
14abstraction_element!(LinEventTriggeredFrame, LinEventTriggeredFrame);
15impl IdentifiableAbstractionElement for LinEventTriggeredFrame {}
16
17impl LinEventTriggeredFrame {}
18
19impl AbstractFrame for LinEventTriggeredFrame {
20    type FrameTriggeringType = LinFrameTriggering;
21
22    /// List all [`LinFrameTriggering`]s using this frame
23    fn frame_triggerings(&self) -> Vec<LinFrameTriggering> {
24        let model_result = self.element().model();
25        let path_result = self.element().path();
26        if let (Ok(model), Ok(path)) = (model_result, path_result) {
27            model
28                .get_references_to(&path)
29                .iter()
30                .filter_map(|e| {
31                    e.upgrade()
32                        .and_then(|ref_elem| ref_elem.named_parent().ok().flatten())
33                        .and_then(|elem| LinFrameTriggering::try_from(elem).ok())
34                })
35                .collect()
36        } else {
37            vec![]
38        }
39    }
40
41    /// map a PDU to the frame
42    fn map_pdu<T: AbstractPdu>(
43        &self,
44        gen_pdu: &T,
45        start_position: u32,
46        byte_order: ByteOrder,
47        update_bit: Option<u32>,
48    ) -> Result<PduToFrameMapping, AutosarAbstractionError> {
49        Frame::Lin(LinFrame::EventTriggered(self.clone())).map_pdu(gen_pdu, start_position, byte_order, update_bit)
50    }
51}
52
53//##################################################################
54
55/// A frame on a LIN bus
56#[derive(Debug, Clone, PartialEq, Eq, Hash)]
57pub struct LinSporadicFrame(Element);
58abstraction_element!(LinSporadicFrame, LinSporadicFrame);
59impl IdentifiableAbstractionElement for LinSporadicFrame {}
60
61impl LinSporadicFrame {}
62
63impl AbstractFrame for LinSporadicFrame {
64    type FrameTriggeringType = LinFrameTriggering;
65
66    /// List all [`LinFrameTriggering`]s using this frame
67    fn frame_triggerings(&self) -> Vec<LinFrameTriggering> {
68        let model_result = self.element().model();
69        let path_result = self.element().path();
70        if let (Ok(model), Ok(path)) = (model_result, path_result) {
71            model
72                .get_references_to(&path)
73                .iter()
74                .filter_map(|e| {
75                    e.upgrade()
76                        .and_then(|ref_elem| ref_elem.named_parent().ok().flatten())
77                        .and_then(|elem| LinFrameTriggering::try_from(elem).ok())
78                })
79                .collect()
80        } else {
81            vec![]
82        }
83    }
84
85    /// map a PDU to the frame
86    fn map_pdu<T: AbstractPdu>(
87        &self,
88        gen_pdu: &T,
89        start_position: u32,
90        byte_order: ByteOrder,
91        update_bit: Option<u32>,
92    ) -> Result<PduToFrameMapping, AutosarAbstractionError> {
93        Frame::Lin(LinFrame::Sporadic(self.clone())).map_pdu(gen_pdu, start_position, byte_order, update_bit)
94    }
95}
96
97//##################################################################
98
99/// A frame on a LIN bus
100#[derive(Debug, Clone, PartialEq, Eq, Hash)]
101pub struct LinUnconditionalFrame(Element);
102abstraction_element!(LinUnconditionalFrame, LinUnconditionalFrame);
103impl IdentifiableAbstractionElement for LinUnconditionalFrame {}
104
105impl LinUnconditionalFrame {}
106
107impl AbstractFrame for LinUnconditionalFrame {
108    type FrameTriggeringType = LinFrameTriggering;
109
110    /// List all [`LinFrameTriggering`]s using this frame
111    fn frame_triggerings(&self) -> Vec<LinFrameTriggering> {
112        let model_result = self.element().model();
113        let path_result = self.element().path();
114        if let (Ok(model), Ok(path)) = (model_result, path_result) {
115            model
116                .get_references_to(&path)
117                .iter()
118                .filter_map(|e| {
119                    e.upgrade()
120                        .and_then(|ref_elem| ref_elem.named_parent().ok().flatten())
121                        .and_then(|elem| LinFrameTriggering::try_from(elem).ok())
122                })
123                .collect()
124        } else {
125            vec![]
126        }
127    }
128
129    /// map a PDU to the frame
130    fn map_pdu<T: AbstractPdu>(
131        &self,
132        gen_pdu: &T,
133        start_position: u32,
134        byte_order: ByteOrder,
135        update_bit: Option<u32>,
136    ) -> Result<PduToFrameMapping, AutosarAbstractionError> {
137        Frame::Lin(LinFrame::Unconditional(self.clone())).map_pdu(gen_pdu, start_position, byte_order, update_bit)
138    }
139}
140
141//##################################################################
142
143/// A frame on a LIN bus
144#[derive(Debug, Clone, PartialEq, Eq, Hash)]
145pub enum LinFrame {
146    /// An event triggered LIN frame
147    EventTriggered(LinEventTriggeredFrame),
148    /// A sporadic LIN frame
149    Sporadic(LinSporadicFrame),
150    /// An unconditional LIN frame
151    Unconditional(LinUnconditionalFrame),
152}
153impl AbstractionElement for LinFrame {
154    fn element(&self) -> &autosar_data::Element {
155        match self {
156            LinFrame::EventTriggered(ftf) => ftf.element(),
157            LinFrame::Sporadic(fs) => fs.element(),
158            LinFrame::Unconditional(fu) => fu.element(),
159        }
160    }
161}
162
163impl TryFrom<Element> for LinFrame {
164    type Error = AutosarAbstractionError;
165
166    fn try_from(element: Element) -> Result<Self, Self::Error> {
167        match element.element_name() {
168            ElementName::LinEventTriggeredFrame => {
169                Ok(LinFrame::EventTriggered(LinEventTriggeredFrame::try_from(element)?))
170            }
171            ElementName::LinSporadicFrame => Ok(LinFrame::Sporadic(LinSporadicFrame::try_from(element)?)),
172            ElementName::LinUnconditionalFrame => {
173                Ok(LinFrame::Unconditional(LinUnconditionalFrame::try_from(element)?))
174            }
175            _ => Err(AutosarAbstractionError::ConversionError {
176                element,
177                dest: "LinFrame".to_string(),
178            }),
179        }
180    }
181}
182
183impl AbstractFrame for LinFrame {
184    type FrameTriggeringType = LinFrameTriggering;
185
186    /// List all [`LinFrameTriggering`]s using this frame
187    fn frame_triggerings(&self) -> Vec<LinFrameTriggering> {
188        match self {
189            LinFrame::EventTriggered(ftf) => ftf.frame_triggerings(),
190            LinFrame::Sporadic(fs) => fs.frame_triggerings(),
191            LinFrame::Unconditional(fu) => fu.frame_triggerings(),
192        }
193    }
194
195    /// map a PDU to the frame
196    fn map_pdu<T: AbstractPdu>(
197        &self,
198        gen_pdu: &T,
199        start_position: u32,
200        byte_order: ByteOrder,
201        update_bit: Option<u32>,
202    ) -> Result<PduToFrameMapping, AutosarAbstractionError> {
203        match self {
204            LinFrame::EventTriggered(ftf) => ftf.map_pdu(gen_pdu, start_position, byte_order, update_bit),
205            LinFrame::Sporadic(fs) => fs.map_pdu(gen_pdu, start_position, byte_order, update_bit),
206            LinFrame::Unconditional(fu) => fu.map_pdu(gen_pdu, start_position, byte_order, update_bit),
207        }
208    }
209}
210
211//##################################################################
212
213/// The frame triggering connects a frame to a physical channel
214#[derive(Debug, Clone, PartialEq, Eq, Hash)]
215pub struct LinFrameTriggering(Element);
216abstraction_element!(LinFrameTriggering, LinFrameTriggering);
217impl IdentifiableAbstractionElement for LinFrameTriggering {}
218
219impl LinFrameTriggering {}
220
221impl AbstractFrameTriggering for LinFrameTriggering {
222    type FrameType = LinFrame;
223}
224
225impl From<LinFrameTriggering> for FrameTriggering {
226    fn from(cft: LinFrameTriggering) -> Self {
227        FrameTriggering::Lin(cft)
228    }
229}