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}