autosar_data_abstraction/communication/physical_channel/
can.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
use crate::{
    abstraction_element,
    communication::{
        AbstractPhysicalChannel, CanAddressingMode, CanCluster, CanCommunicationConnector, CanFrame,
        CanFrameTriggering, CanFrameType,
    },
    AbstractionElement, AutosarAbstractionError,
};
use autosar_data::{Element, ElementName};

/// The `CanPhysicalChannel contains all of the communication on a CAN network
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct CanPhysicalChannel(Element);
abstraction_element!(CanPhysicalChannel, CanPhysicalChannel);

impl CanPhysicalChannel {
    /// get the cluster containing this physical channel
    ///
    /// # Example
    ///
    /// ```
    /// # use autosar_data::*;
    /// # use autosar_data_abstraction::*;
    /// # use autosar_data_abstraction::communication::*;
    /// # let model = AutosarModel::new();
    /// # model.create_file("filename", AutosarVersion::Autosar_00048).unwrap();
    /// # let package = ArPackage::get_or_create(&model, "/pkg1").unwrap();
    /// # let system = package.create_system("System", SystemCategory::SystemExtract).unwrap();
    /// # let cluster = system.create_can_cluster("Cluster", &package, &CanClusterSettings::default()).unwrap();
    /// let channel = cluster.create_physical_channel("Channel").unwrap();
    /// let cluster_2 = channel.cluster().unwrap();
    /// assert_eq!(cluster, cluster_2);
    /// ```
    pub fn cluster(&self) -> Result<CanCluster, AutosarAbstractionError> {
        let cluster_elem = self.0.named_parent()?.unwrap();
        CanCluster::try_from(cluster_elem)
    }

    /// add a trigger for a CAN frame in this physical channel
    ///
    /// # Example
    ///
    /// ```
    /// # use autosar_data::*;
    /// # use autosar_data_abstraction::*;
    /// # use autosar_data_abstraction::communication::*;
    /// # let model = AutosarModel::new();
    /// # model.create_file("filename", AutosarVersion::Autosar_00048).unwrap();
    /// # let package = ArPackage::get_or_create(&model, "/pkg1").unwrap();
    /// # let frame_package = ArPackage::get_or_create(&model, "/Frames").unwrap();
    /// # let system = package.create_system("System", SystemCategory::SystemExtract).unwrap();
    /// # let cluster = system.create_can_cluster("Cluster", &package, &CanClusterSettings::default()).unwrap();
    /// let channel = cluster.create_physical_channel("Channel").unwrap();
    /// let frame = system.create_can_frame("Frame", &frame_package, 8).unwrap();
    /// channel.trigger_frame(&frame, 0x100, CanAddressingMode::Standard, CanFrameType::Can20).unwrap();
    /// ```
    pub fn trigger_frame(
        &self,
        frame: &CanFrame,
        identifier: u32,
        addressing_mode: CanAddressingMode,
        frame_type: CanFrameType,
    ) -> Result<CanFrameTriggering, AutosarAbstractionError> {
        CanFrameTriggering::new(self, frame, identifier, addressing_mode, frame_type)
    }

    /// iterate over all frame triggerings of this physical channel
    ///
    /// # Example
    ///
    /// ```
    /// # use autosar_data::*;
    /// # use autosar_data_abstraction::{*, communication::*};
    /// # fn main() -> Result<(), AutosarAbstractionError> {
    /// # let model = AutosarModel::new();
    /// # model.create_file("filename", AutosarVersion::LATEST)?;
    /// # let package = ArPackage::get_or_create(&model, "/pkg1")?;
    /// # let system = package.create_system("System", SystemCategory::SystemExtract)?;
    /// # let cluster = system.create_can_cluster("Cluster", &package, &CanClusterSettings::default())?;
    /// # let channel = cluster.create_physical_channel("Channel")?;
    /// # let frame = system.create_can_frame("Frame", &package, 8)?;
    /// channel.trigger_frame(&frame, 0x100, CanAddressingMode::Standard, CanFrameType::Can20)?;
    /// for ft in channel.frame_triggerings() {
    ///     println!("Frame triggering: {:?}", ft);
    /// }
    /// # assert_eq!(channel.frame_triggerings().count(), 1);
    /// # Ok(())}
    pub fn frame_triggerings(&self) -> impl Iterator<Item = CanFrameTriggering> {
        self.0
            .get_sub_element(ElementName::FrameTriggerings)
            .into_iter()
            .flat_map(|elem| elem.sub_elements())
            .filter_map(|elem| CanFrameTriggering::try_from(elem).ok())
    }
}

impl AbstractPhysicalChannel for CanPhysicalChannel {
    type CommunicationConnectorType = CanCommunicationConnector;
}

//##################################################################

#[cfg(test)]
mod test {
    use crate::{communication::CanClusterSettings, ArPackage, SystemCategory};
    use autosar_data::{AutosarModel, AutosarVersion};

    #[test]
    fn channel() {
        let model = AutosarModel::new();
        model.create_file("filename", AutosarVersion::Autosar_00048).unwrap();
        let pkg = ArPackage::get_or_create(&model, "/test").unwrap();
        let system = pkg.create_system("System", SystemCategory::SystemDescription).unwrap();
        let settings = CanClusterSettings::default();
        let cluster = system.create_can_cluster("CanCluster", &pkg, &settings).unwrap();

        let channel = cluster.create_physical_channel("channel_name").unwrap();
        let c2 = channel.cluster().unwrap();
        assert_eq!(cluster, c2);
    }
}