autosar_data_abstraction/communication/controller/
lin.rs

1use crate::{
2    AbstractionElement, AutosarAbstractionError, EcuInstance, IdentifiableAbstractionElement, abstraction_element,
3    communication::{AbstractCommunicationConnector, AbstractCommunicationController},
4};
5use autosar_data::{AutosarDataError, Element, ElementName};
6
7//##################################################################
8
9/// An `EcuInstance` needs a `LinMaster` or `LinSlave` in order to connect to a LIN cluster.
10#[derive(Debug, Clone, PartialEq, Eq, Hash)]
11pub struct LinMaster(Element);
12abstraction_element!(LinMaster, LinMaster);
13impl IdentifiableAbstractionElement for LinMaster {}
14
15impl LinMaster {
16    // create a new LinMaster - called by EcuInstance::create_lin_master_communication_controller
17    pub(crate) fn new(name: &str, ecu: &EcuInstance) -> Result<Self, AutosarAbstractionError> {
18        let commcontrollers = ecu.element().get_or_create_sub_element(ElementName::CommControllers)?;
19        let ctrl = commcontrollers.create_named_sub_element(ElementName::LinMaster, name)?;
20        let _lincc = ctrl
21            .create_sub_element(ElementName::LinMasterVariants)?
22            .create_sub_element(ElementName::LinMasterConditional)?;
23
24        Ok(Self(ctrl))
25    }
26}
27
28impl AbstractCommunicationController for LinMaster {}
29
30//##################################################################
31
32/// An `EcuInstance` needs a `LinMaster` or `LinSlave` in order to connect to a LIN cluster.
33#[derive(Debug, Clone, PartialEq, Eq, Hash)]
34pub struct LinSlave(Element);
35abstraction_element!(LinSlave, LinSlave);
36impl IdentifiableAbstractionElement for LinSlave {}
37
38impl LinSlave {
39    // create a new LinSlave - called by EcuInstance::create_lin_slave_communication_controller
40    pub(crate) fn new(name: &str, ecu: &EcuInstance) -> Result<Self, AutosarAbstractionError> {
41        let commcontrollers = ecu.element().get_or_create_sub_element(ElementName::CommControllers)?;
42        let ctrl = commcontrollers.create_named_sub_element(ElementName::LinSlave, name)?;
43        let _linsc = ctrl
44            .create_sub_element(ElementName::LinSlaveVariants)?
45            .create_sub_element(ElementName::LinSlaveConditional)?;
46
47        Ok(Self(ctrl))
48    }
49}
50
51impl AbstractCommunicationController for LinSlave {}
52
53//##################################################################
54
55/// A connector between a [`LinMaster`] or [`LinSlave`] in an ECU and a [`LinPhysicalChannel`]
56#[derive(Debug, Clone, PartialEq, Eq, Hash)]
57pub struct LinCommunicationConnector(Element);
58abstraction_element!(LinCommunicationConnector, LinCommunicationConnector);
59impl IdentifiableAbstractionElement for LinCommunicationConnector {}
60
61impl LinCommunicationConnector {}
62
63impl AbstractCommunicationConnector for LinCommunicationConnector {
64    type CommunicationControllerType = LinCommunicationController;
65
66    fn controller(&self) -> Result<Self::CommunicationControllerType, AutosarAbstractionError> {
67        let controller = self
68            .element()
69            .get_sub_element(ElementName::CommControllerRef)
70            .ok_or_else(|| {
71                AutosarAbstractionError::ModelError(AutosarDataError::ElementNotFound {
72                    target: ElementName::CommControllerRef,
73                    parent: self.element().element_name(),
74                })
75            })?
76            .get_reference_target()?;
77        LinCommunicationController::try_from(controller)
78    }
79}
80
81//##################################################################
82
83/// A LIN communication controller is either a [`LinMaster`] or a [`LinSlave`].
84#[derive(Debug, Clone, PartialEq, Eq, Hash)]
85pub enum LinCommunicationController {
86    /// A LIN Master communication controller
87    Master(LinMaster),
88    /// A LIN Slave communication controller
89    Slave(LinSlave),
90}
91impl AbstractionElement for LinCommunicationController {
92    fn element(&self) -> &autosar_data::Element {
93        match self {
94            LinCommunicationController::Master(master) => master.element(),
95            LinCommunicationController::Slave(slave) => slave.element(),
96        }
97    }
98}
99impl AbstractCommunicationController for LinCommunicationController {}
100
101impl TryFrom<Element> for LinCommunicationController {
102    type Error = AutosarAbstractionError;
103
104    fn try_from(element: Element) -> Result<Self, Self::Error> {
105        match element.element_name() {
106            ElementName::LinMaster => Ok(Self::Master(LinMaster::try_from(element)?)),
107            ElementName::LinSlave => Ok(Self::Slave(LinSlave::try_from(element)?)),
108            _ => Err(AutosarAbstractionError::ConversionError {
109                element,
110                dest: "LinCommunicationController".to_string(),
111            }),
112        }
113    }
114}