autosar_data_abstraction/communication/physical_channel/can.rs
1use 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/// The `CanPhysicalChannel` contains all of the communication on a CAN network
11#[derive(Debug, Clone, PartialEq, Eq, Hash)]
12pub struct CanPhysicalChannel(Element);
13abstraction_element!(CanPhysicalChannel, CanPhysicalChannel);
14impl IdentifiableAbstractionElement for CanPhysicalChannel {}
15
16impl CanPhysicalChannel {
17 /// get the cluster containing this physical channel
18 ///
19 /// # Example
20 ///
21 /// ```
22 /// # use autosar_data::*;
23 /// # use autosar_data_abstraction::*;
24 /// # use autosar_data_abstraction::communication::*;
25 /// # fn main() -> Result<(), AutosarAbstractionError> {
26 /// # let model = AutosarModelAbstraction::create("filename", AutosarVersion::Autosar_00048);
27 /// # let package = model.get_or_create_package("/pkg1")?;
28 /// # let system = package.create_system("System", SystemCategory::SystemExtract)?;
29 /// # let cluster = system.create_can_cluster("Cluster", &package, None)?;
30 /// let channel = cluster.create_physical_channel("Channel")?;
31 /// let cluster_2 = channel.cluster()?;
32 /// assert_eq!(cluster, cluster_2);
33 /// # Ok(())}
34 /// ```
35 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 /// add a trigger for a CAN frame in this physical channel
41 ///
42 /// # Example
43 ///
44 /// ```
45 /// # use autosar_data::*;
46 /// # use autosar_data_abstraction::*;
47 /// # use autosar_data_abstraction::communication::*;
48 /// # fn main() -> Result<(), AutosarAbstractionError> {
49 /// # let model = AutosarModelAbstraction::create("filename", AutosarVersion::Autosar_00048);
50 /// # let package = model.get_or_create_package("/pkg1")?;
51 /// # let frame_package = model.get_or_create_package("/Frames")?;
52 /// # let system = package.create_system("System", SystemCategory::SystemExtract)?;
53 /// # let cluster = system.create_can_cluster("Cluster", &package, None)?;
54 /// let channel = cluster.create_physical_channel("Channel")?;
55 /// let frame = system.create_can_frame("Frame", &frame_package, 8)?;
56 /// channel.trigger_frame(&frame, 0x100, CanAddressingMode::Standard, CanFrameType::Can20)?;
57 /// # Ok(())}
58 /// ```
59 pub fn trigger_frame(
60 &self,
61 frame: &CanFrame,
62 identifier: u32,
63 addressing_mode: CanAddressingMode,
64 frame_type: CanFrameType,
65 ) -> Result<CanFrameTriggering, AutosarAbstractionError> {
66 CanFrameTriggering::new(self, frame, identifier, addressing_mode, frame_type)
67 }
68
69 /// iterate over all frame triggerings of this physical channel
70 ///
71 /// # Example
72 ///
73 /// ```
74 /// # use autosar_data::*;
75 /// # use autosar_data_abstraction::{*, communication::*};
76 /// # fn main() -> Result<(), AutosarAbstractionError> {
77 /// # let model = AutosarModelAbstraction::create("filename", AutosarVersion::LATEST);
78 /// # let package = model.get_or_create_package("/pkg1")?;
79 /// # let system = package.create_system("System", SystemCategory::SystemExtract)?;
80 /// # let cluster = system.create_can_cluster("Cluster", &package, None)?;
81 /// # let channel = cluster.create_physical_channel("Channel")?;
82 /// # let frame = system.create_can_frame("Frame", &package, 8)?;
83 /// channel.trigger_frame(&frame, 0x100, CanAddressingMode::Standard, CanFrameType::Can20)?;
84 /// for ft in channel.frame_triggerings() {
85 /// println!("Frame triggering: {:?}", ft);
86 /// }
87 /// # assert_eq!(channel.frame_triggerings().count(), 1);
88 /// # Ok(())}
89 pub fn frame_triggerings(&self) -> impl Iterator<Item = CanFrameTriggering> + Send + use<> {
90 self.0
91 .get_sub_element(ElementName::FrameTriggerings)
92 .into_iter()
93 .flat_map(|elem| elem.sub_elements())
94 .filter_map(|elem| CanFrameTriggering::try_from(elem).ok())
95 }
96}
97
98impl From<CanPhysicalChannel> for PhysicalChannel {
99 fn from(channel: CanPhysicalChannel) -> Self {
100 PhysicalChannel::Can(channel)
101 }
102}
103
104impl AbstractPhysicalChannel for CanPhysicalChannel {
105 type CommunicationConnectorType = CanCommunicationConnector;
106}
107
108//##################################################################
109
110#[cfg(test)]
111mod test {
112 use crate::{AutosarModelAbstraction, SystemCategory, communication::PhysicalChannel};
113 use autosar_data::AutosarVersion;
114
115 #[test]
116 fn channel() {
117 let model = AutosarModelAbstraction::create("filename", AutosarVersion::Autosar_00048);
118 let pkg = model.get_or_create_package("/test").unwrap();
119 let system = pkg.create_system("System", SystemCategory::SystemDescription).unwrap();
120 let cluster = system.create_can_cluster("CanCluster", &pkg, None).unwrap();
121
122 let channel = cluster.create_physical_channel("channel_name").unwrap();
123 let c2 = channel.cluster().unwrap();
124 assert_eq!(cluster, c2);
125
126 let wrapped_channel: PhysicalChannel = channel.clone().into();
127 assert_eq!(wrapped_channel, PhysicalChannel::Can(channel));
128 }
129}