autosar_data_abstraction/communication/physical_channel/
flexray.rs1use crate::{
2 AbstractionElement, AutosarAbstractionError, IdentifiableAbstractionElement, abstraction_element,
3 communication::{
4 AbstractPhysicalChannel, FlexrayCluster, FlexrayCommunicationConnector, FlexrayCommunicationCycle,
5 FlexrayFrame, FlexrayFrameTriggering, PhysicalChannel,
6 },
7};
8use autosar_data::{Element, ElementName, EnumItem};
9
10#[derive(Debug, Clone, PartialEq, Eq, Hash)]
12pub struct FlexrayPhysicalChannel(Element);
13abstraction_element!(FlexrayPhysicalChannel, FlexrayPhysicalChannel);
14impl IdentifiableAbstractionElement for FlexrayPhysicalChannel {}
15
16impl FlexrayPhysicalChannel {
17 #[must_use]
19 pub fn channel_name(&self) -> Option<FlexrayChannelName> {
20 let cn = self
21 .0
22 .get_sub_element(ElementName::ChannelName)?
23 .character_data()?
24 .enum_value()?;
25 match cn {
26 EnumItem::ChannelA => Some(FlexrayChannelName::A),
27 EnumItem::ChannelB => Some(FlexrayChannelName::B),
28 _ => None,
29 }
30 }
31
32 pub fn remove(self, deep: bool) -> Result<(), AutosarAbstractionError> {
34 for ft in self.frame_triggerings() {
36 ft.remove(deep)?;
37 }
38
39 for pt in self.pdu_triggerings() {
41 pt.remove(deep)?;
42 }
43
44 for st in self.signal_triggerings() {
46 st.remove(deep)?;
47 }
48
49 for connector in self.connectors() {
51 connector.remove(deep)?;
52 }
53
54 AbstractionElement::remove(self, deep)
55 }
56
57 pub fn cluster(&self) -> Result<FlexrayCluster, AutosarAbstractionError> {
80 let cluster_elem = self.0.named_parent()?.unwrap();
81 FlexrayCluster::try_from(cluster_elem)
82 }
83
84 pub fn trigger_frame(
105 &self,
106 frame: &FlexrayFrame,
107 slot_id: u16,
108 timing: &FlexrayCommunicationCycle,
109 ) -> Result<FlexrayFrameTriggering, AutosarAbstractionError> {
110 FlexrayFrameTriggering::new(self, frame, slot_id, timing)
111 }
112
113 pub fn frame_triggerings(&self) -> impl Iterator<Item = FlexrayFrameTriggering> + Send + use<> {
135 self.0
136 .get_sub_element(ElementName::FrameTriggerings)
137 .into_iter()
138 .flat_map(|elem| elem.sub_elements())
139 .filter_map(|elem| FlexrayFrameTriggering::try_from(elem).ok())
140 }
141}
142
143impl From<FlexrayPhysicalChannel> for PhysicalChannel {
144 fn from(channel: FlexrayPhysicalChannel) -> Self {
145 PhysicalChannel::Flexray(channel)
146 }
147}
148
149impl AbstractPhysicalChannel for FlexrayPhysicalChannel {
150 type CommunicationConnectorType = FlexrayCommunicationConnector;
151}
152
153#[derive(Debug, Clone, Copy, PartialEq, Eq)]
159pub enum FlexrayChannelName {
160 A,
162 B,
164}
165
166#[cfg(test)]
169mod test {
170 use crate::{
171 AbstractionElement, AutosarModelAbstraction, ByteOrder, SystemCategory,
172 communication::{AbstractFrame, FlexrayChannelName, FlexrayClusterSettings},
173 };
174 use autosar_data::{AutosarVersion, ElementName};
175
176 #[test]
177 fn channel() {
178 let model = AutosarModelAbstraction::create("filename", AutosarVersion::Autosar_00048);
179 let pkg = model.get_or_create_package("/test").unwrap();
180 let system = pkg.create_system("System", SystemCategory::SystemDescription).unwrap();
181 let settings = FlexrayClusterSettings::default();
182 let cluster = system.create_flexray_cluster("FlxCluster", &pkg, &settings).unwrap();
183
184 let channel = cluster
185 .create_physical_channel("channel_name", FlexrayChannelName::A)
186 .unwrap();
187 let c2 = channel.cluster().unwrap();
188 assert_eq!(cluster, c2);
189
190 let wrapped_channel: super::PhysicalChannel = channel.clone().into();
191 assert_eq!(wrapped_channel, super::PhysicalChannel::Flexray(channel.clone()));
192
193 let elem_channelname = channel.element().get_sub_element(ElementName::ChannelName).unwrap();
195 elem_channelname.remove_character_data().unwrap();
196 assert!(channel.channel_name().is_none());
197
198 let channel2 = cluster.create_physical_channel("channel_name2", FlexrayChannelName::A);
200 assert!(channel2.is_ok());
201 }
202
203 #[test]
204 fn remove_channel() {
205 let model = AutosarModelAbstraction::create("filename", AutosarVersion::LATEST);
206 let pkg = model.get_or_create_package("/test").unwrap();
207 let system = pkg.create_system("System", SystemCategory::SystemDescription).unwrap();
208 let settings = FlexrayClusterSettings::default();
209 let cluster = system.create_flexray_cluster("FlxCluster", &pkg, &settings).unwrap();
210
211 let channel = cluster
212 .create_physical_channel("channel_name", FlexrayChannelName::A)
213 .unwrap();
214
215 let frame = system.create_flexray_frame("FlexrayFrame", &pkg, 8).unwrap();
216 let timing = crate::communication::FlexrayCommunicationCycle::Repetition {
217 base_cycle: 1,
218 cycle_repetition: crate::communication::CycleRepetition::C1,
219 };
220 let _ = channel.trigger_frame(&frame, 1, &timing).unwrap();
221 let isignal_ipdu = system.create_isignal_ipdu("ISignalIPdu", &pkg, 8).unwrap();
222 let _ = frame
223 .map_pdu(&isignal_ipdu, 0, ByteOrder::MostSignificantByteLast, None)
224 .unwrap();
225
226 channel.remove(true).unwrap();
227
228 assert!(cluster.physical_channels().channel_a.is_none());
229 assert!(cluster.physical_channels().channel_b.is_none());
230
231 assert!(isignal_ipdu.element().parent().is_err());
233 }
234}