autosar_data_abstraction/communication/physical_channel/
lin.rs1use crate::{
2 AbstractionElement, AutosarAbstractionError, IdentifiableAbstractionElement, abstraction_element,
3 communication::{
4 AbstractPhysicalChannel, LinCluster, LinCommunicationConnector, LinFrame, LinFrameTriggering, PhysicalChannel,
5 },
6};
7use autosar_data::{Element, ElementName};
8
9#[derive(Debug, Clone, PartialEq, Eq, Hash)]
13pub struct LinPhysicalChannel(Element);
14abstraction_element!(LinPhysicalChannel, LinPhysicalChannel);
15impl IdentifiableAbstractionElement for LinPhysicalChannel {}
16
17impl LinPhysicalChannel {
18 pub fn cluster(&self) -> Result<LinCluster, AutosarAbstractionError> {
37 let cluster_elem = self.0.named_parent()?.unwrap();
38 LinCluster::try_from(cluster_elem)
39 }
40
41 pub fn remove(self, deep: bool) -> Result<(), AutosarAbstractionError> {
43 for ft in self.frame_triggerings() {
45 ft.remove(deep)?;
46 }
47
48 for pt in self.pdu_triggerings() {
50 pt.remove(deep)?;
51 }
52
53 for st in self.signal_triggerings() {
55 st.remove(deep)?;
56 }
57
58 for connector in self.connectors() {
60 connector.remove(deep)?;
61 }
62
63 AbstractionElement::remove(self, deep)
64 }
65
66 pub fn trigger_frame<T: Into<LinFrame> + AbstractionElement>(
68 &self,
69 frame: &T,
70 identifier: u32,
71 ) -> Result<LinFrameTriggering, AutosarAbstractionError> {
72 LinFrameTriggering::new(self, &frame.clone().into(), identifier)
73 }
74
75 pub fn frame_triggerings(&self) -> impl Iterator<Item = LinFrameTriggering> + Send + use<> {
77 self.0
78 .get_sub_element(ElementName::FrameTriggerings)
79 .into_iter()
80 .flat_map(|elem| elem.sub_elements())
81 .filter_map(|elem| LinFrameTriggering::try_from(elem).ok())
82 }
83}
84
85impl From<LinPhysicalChannel> for PhysicalChannel {
86 fn from(channel: LinPhysicalChannel) -> Self {
87 PhysicalChannel::Lin(channel)
88 }
89}
90
91impl AbstractPhysicalChannel for LinPhysicalChannel {
92 type CommunicationConnectorType = LinCommunicationConnector;
93}
94
95#[cfg(test)]
98mod test {
99 use crate::{
100 AbstractionElement, AutosarModelAbstraction, ByteOrder, SystemCategory,
101 communication::{AbstractFrame, AbstractPhysicalChannel, PhysicalChannel},
102 };
103 use autosar_data::AutosarVersion;
104
105 #[test]
106 fn channel() {
107 let model = AutosarModelAbstraction::create("filename", AutosarVersion::Autosar_00048);
108 let pkg = model.get_or_create_package("/test").unwrap();
109 let system = pkg.create_system("System", SystemCategory::SystemDescription).unwrap();
110 let cluster = system.create_lin_cluster("CanCluster", &pkg).unwrap();
111
112 let channel = cluster.create_physical_channel("channel_name").unwrap();
113 let c2 = channel.cluster().unwrap();
114 assert_eq!(cluster, c2);
115
116 let wrapped_channel: PhysicalChannel = channel.clone().into();
117 assert_eq!(wrapped_channel, PhysicalChannel::Lin(channel));
118 }
119
120 #[test]
121 fn remove_channel() {
122 let model = AutosarModelAbstraction::create("filename", AutosarVersion::LATEST);
123 let pkg = model.get_or_create_package("/test").unwrap();
124 let system = pkg.create_system("System", SystemCategory::SystemDescription).unwrap();
125 let cluster = system.create_lin_cluster("LinCluster", &pkg).unwrap();
126
127 let channel = cluster.create_physical_channel("channel_name").unwrap();
128
129 let frame = system.create_lin_unconditional_frame("LinFrame", &pkg, 8).unwrap();
130 let _ = channel.trigger_frame(&frame, 0x123).unwrap();
131 let isignal_ipdu = system.create_isignal_ipdu("ISignalIPdu", &pkg, 8).unwrap();
132 let _ = frame
133 .map_pdu(&isignal_ipdu, 0, ByteOrder::MostSignificantByteLast, None)
134 .unwrap();
135
136 assert_eq!(channel.frame_triggerings().count(), 1);
137 assert_eq!(channel.pdu_triggerings().count(), 1);
138
139 channel.remove(true).unwrap();
140 assert!(cluster.physical_channel().is_none());
141 assert!(isignal_ipdu.element().parent().is_err());
143 }
144}