autosar_data_abstraction/communication/physical_channel/
can.rs1use crate::{
2 AbstractionElement, AutosarAbstractionError, IdentifiableAbstractionElement, abstraction_element,
3 communication::{
4 AbstractPhysicalChannel, CanAddressingMode, CanCluster, CanCommunicationConnector, CanFrame,
5 CanFrameTriggering, CanFrameType, PhysicalChannel,
6 },
7};
8use autosar_data::{Element, ElementName};
9
10#[derive(Debug, Clone, PartialEq, Eq, Hash)]
12pub struct CanPhysicalChannel(Element);
13abstraction_element!(CanPhysicalChannel, CanPhysicalChannel);
14impl IdentifiableAbstractionElement for CanPhysicalChannel {}
15
16impl CanPhysicalChannel {
17 pub fn cluster(&self) -> Result<CanCluster, AutosarAbstractionError> {
36 let cluster_elem = self.0.named_parent()?.unwrap();
37 CanCluster::try_from(cluster_elem)
38 }
39
40 pub fn remove(self, deep: bool) -> Result<(), AutosarAbstractionError> {
42 for ft in self.frame_triggerings() {
44 ft.remove(deep)?;
45 }
46
47 for pt in self.pdu_triggerings() {
49 pt.remove(deep)?;
50 }
51
52 for st in self.signal_triggerings() {
54 st.remove(deep)?;
55 }
56
57 for connector in self.connectors() {
59 connector.remove(deep)?;
60 }
61
62 AbstractionElement::remove(self, deep)
63 }
64
65 pub fn trigger_frame(
85 &self,
86 frame: &CanFrame,
87 identifier: u32,
88 addressing_mode: CanAddressingMode,
89 frame_type: CanFrameType,
90 ) -> Result<CanFrameTriggering, AutosarAbstractionError> {
91 CanFrameTriggering::new(self, frame, identifier, addressing_mode, frame_type)
92 }
93
94 pub fn frame_triggerings(&self) -> impl Iterator<Item = CanFrameTriggering> + Send + use<> {
115 self.0
116 .get_sub_element(ElementName::FrameTriggerings)
117 .into_iter()
118 .flat_map(|elem| elem.sub_elements())
119 .filter_map(|elem| CanFrameTriggering::try_from(elem).ok())
120 }
121}
122
123impl From<CanPhysicalChannel> for PhysicalChannel {
124 fn from(channel: CanPhysicalChannel) -> Self {
125 PhysicalChannel::Can(channel)
126 }
127}
128
129impl AbstractPhysicalChannel for CanPhysicalChannel {
130 type CommunicationConnectorType = CanCommunicationConnector;
131}
132
133#[cfg(test)]
136mod test {
137 use crate::{
138 AbstractionElement, AutosarModelAbstraction, ByteOrder, SystemCategory,
139 communication::{AbstractFrame, AbstractPhysicalChannel, CanAddressingMode, CanFrameType, PhysicalChannel},
140 };
141 use autosar_data::AutosarVersion;
142
143 #[test]
144 fn channel() {
145 let model = AutosarModelAbstraction::create("filename", AutosarVersion::Autosar_00048);
146 let pkg = model.get_or_create_package("/test").unwrap();
147 let system = pkg.create_system("System", SystemCategory::SystemDescription).unwrap();
148 let cluster = system.create_can_cluster("CanCluster", &pkg, None).unwrap();
149
150 let channel = cluster.create_physical_channel("channel_name").unwrap();
151 let c2 = channel.cluster().unwrap();
152 assert_eq!(cluster, c2);
153
154 let wrapped_channel: PhysicalChannel = channel.clone().into();
155 assert_eq!(wrapped_channel, PhysicalChannel::Can(channel));
156 }
157
158 #[test]
159 fn remove_channel() {
160 let model = AutosarModelAbstraction::create("filename", AutosarVersion::LATEST);
161 let pkg = model.get_or_create_package("/test").unwrap();
162 let system = pkg.create_system("System", SystemCategory::SystemDescription).unwrap();
163 let cluster = system.create_can_cluster("CanCluster", &pkg, None).unwrap();
164
165 let channel = cluster.create_physical_channel("channel_name").unwrap();
166
167 let frame = system.create_can_frame("CanFrame", &pkg, 8).unwrap();
168 let _ = channel
169 .trigger_frame(&frame, 0x123, CanAddressingMode::Standard, CanFrameType::Can20)
170 .unwrap();
171 let isignal_ipdu = system.create_isignal_ipdu("ISignalIPdu", &pkg, 8).unwrap();
172 let _ = frame
173 .map_pdu(&isignal_ipdu, 0, ByteOrder::MostSignificantByteLast, None)
174 .unwrap();
175
176 assert_eq!(channel.frame_triggerings().count(), 1);
177 assert_eq!(channel.pdu_triggerings().count(), 1);
178
179 channel.remove(true).unwrap();
180 assert!(cluster.physical_channel().is_none());
181 assert!(isignal_ipdu.element().parent().is_err());
183 }
184}