autosar_data_abstraction/communication/controller/
mod.rs1use crate::{AbstractionElement, AutosarAbstractionError, EcuInstance, IdentifiableAbstractionElement};
2use autosar_data::{AutosarDataError, Element, ElementName};
3
4mod can;
5mod ethernet;
6mod flexray;
7mod lin;
8
9pub use can::*;
10pub use ethernet::*;
11pub use flexray::*;
12pub use lin::*;
13
14#[derive(Debug, Clone, PartialEq, Eq)]
18#[non_exhaustive]
19pub enum CommunicationController {
20 Can(CanCommunicationController),
22 Ethernet(EthernetCommunicationController),
24 Flexray(FlexrayCommunicationController),
26 LinMaster(LinMaster),
28 LinSlave(LinSlave),
30}
31
32impl AbstractionElement for CommunicationController {
33 fn element(&self) -> &autosar_data::Element {
34 match self {
35 CommunicationController::Can(ccc) => ccc.element(),
36 CommunicationController::Ethernet(ecc) => ecc.element(),
37 CommunicationController::Flexray(fcc) => fcc.element(),
38 CommunicationController::LinMaster(lcc) => lcc.element(),
39 CommunicationController::LinSlave(lcc) => lcc.element(),
40 }
41 }
42}
43
44impl TryFrom<Element> for CommunicationController {
45 type Error = AutosarAbstractionError;
46
47 fn try_from(element: Element) -> Result<Self, Self::Error> {
48 match element.element_name() {
49 ElementName::CanCommunicationController => Ok(Self::Can(CanCommunicationController::try_from(element)?)),
50 ElementName::EthernetCommunicationController => {
51 Ok(Self::Ethernet(EthernetCommunicationController::try_from(element)?))
52 }
53 ElementName::FlexrayCommunicationController => {
54 Ok(Self::Flexray(FlexrayCommunicationController::try_from(element)?))
55 }
56 ElementName::LinMaster => Ok(Self::LinMaster(LinMaster::try_from(element)?)),
57 ElementName::LinSlave => Ok(Self::LinSlave(LinSlave::try_from(element)?)),
58 _ => Err(AutosarAbstractionError::ConversionError {
59 element,
60 dest: "CommunicationController".to_string(),
61 }),
62 }
63 }
64}
65
66impl IdentifiableAbstractionElement for CommunicationController {}
67impl AbstractCommunicationController for CommunicationController {}
68
69impl From<CanCommunicationController> for CommunicationController {
70 fn from(value: CanCommunicationController) -> Self {
71 CommunicationController::Can(value)
72 }
73}
74
75impl From<EthernetCommunicationController> for CommunicationController {
76 fn from(value: EthernetCommunicationController) -> Self {
77 CommunicationController::Ethernet(value)
78 }
79}
80
81impl From<FlexrayCommunicationController> for CommunicationController {
82 fn from(value: FlexrayCommunicationController) -> Self {
83 CommunicationController::Flexray(value)
84 }
85}
86
87impl From<LinMaster> for CommunicationController {
88 fn from(value: LinMaster) -> Self {
89 CommunicationController::LinMaster(value)
90 }
91}
92
93impl From<LinSlave> for CommunicationController {
94 fn from(value: LinSlave) -> Self {
95 CommunicationController::LinSlave(value)
96 }
97}
98
99pub trait AbstractCommunicationController: AbstractionElement {
103 fn ecu_instance(&self) -> Result<EcuInstance, AutosarAbstractionError> {
124 self.element().named_parent()?.unwrap().try_into()
128 }
129}
130
131pub trait AbstractCommunicationConnector: AbstractionElement {
135 type CommunicationControllerType: AbstractCommunicationController;
137
138 fn ecu_instance(&self) -> Result<EcuInstance, AutosarAbstractionError> {
140 self.element().named_parent()?.unwrap().try_into()
144 }
145
146 fn controller(&self) -> Result<Self::CommunicationControllerType, AutosarAbstractionError>;
148}
149
150#[derive(Debug, Clone, PartialEq, Eq)]
154pub enum CommunicationConnector {
155 Can(CanCommunicationConnector),
157 Ethernet(EthernetCommunicationConnector),
159 Flexray(FlexrayCommunicationConnector),
161 Lin(LinCommunicationConnector),
163}
164
165impl AbstractionElement for CommunicationConnector {
166 fn element(&self) -> &autosar_data::Element {
167 match self {
168 CommunicationConnector::Can(cc) => cc.element(),
169 CommunicationConnector::Ethernet(ec) => ec.element(),
170 CommunicationConnector::Flexray(fc) => fc.element(),
171 CommunicationConnector::Lin(lc) => lc.element(),
172 }
173 }
174}
175
176impl TryFrom<Element> for CommunicationConnector {
177 type Error = AutosarAbstractionError;
178
179 fn try_from(element: Element) -> Result<Self, Self::Error> {
180 match element.element_name() {
181 ElementName::CanCommunicationConnector => Ok(Self::Can(CanCommunicationConnector::try_from(element)?)),
182 ElementName::EthernetCommunicationConnector => {
183 Ok(Self::Ethernet(EthernetCommunicationConnector::try_from(element)?))
184 }
185 ElementName::FlexrayCommunicationConnector => {
186 Ok(Self::Flexray(FlexrayCommunicationConnector::try_from(element)?))
187 }
188 ElementName::LinCommunicationConnector => Ok(Self::Lin(LinCommunicationConnector::try_from(element)?)),
189 _ => Err(AutosarAbstractionError::ConversionError {
190 element,
191 dest: "CommunicationConnector".to_string(),
192 }),
193 }
194 }
195}
196
197impl IdentifiableAbstractionElement for CommunicationConnector {}
198
199impl AbstractCommunicationConnector for CommunicationConnector {
200 type CommunicationControllerType = CommunicationController;
201
202 fn controller(&self) -> Result<Self::CommunicationControllerType, AutosarAbstractionError> {
203 let Some(controller_ref) = self.element().get_sub_element(ElementName::CommControllerRef) else {
204 return Err(AutosarAbstractionError::ModelError(AutosarDataError::ElementNotFound {
205 target: ElementName::CommControllerRef,
206 parent: self.element().element_name(),
207 }));
208 };
209 let controller = controller_ref.get_reference_target()?;
210 Self::CommunicationControllerType::try_from(controller)
211 }
212}
213
214#[cfg(test)]
217mod tests {
218 use super::*;
219 use crate::{
220 AutosarModelAbstraction, SystemCategory,
221 communication::{FlexrayChannelName, FlexrayClusterSettings},
222 };
223 use autosar_data::AutosarVersion;
224
225 #[test]
226 fn test_communication_controller() {
227 let model = AutosarModelAbstraction::create("filename", AutosarVersion::LATEST);
228 let package = model.get_or_create_package("/test").unwrap();
229 let system = package.create_system("System", SystemCategory::SystemExtract).unwrap();
230
231 let ecu = system.create_ecu_instance("ecu", &package).unwrap();
232 let can_ctrl = ecu.create_can_communication_controller("can").unwrap();
233 let ethernet_ctrl = ecu.create_ethernet_communication_controller("ethernet", None).unwrap();
234 let flexray_ctrl = ecu.create_flexray_communication_controller("flexray").unwrap();
235
236 let can_cc: CommunicationController = can_ctrl.clone().into();
237 let ethernet_cc: CommunicationController = ethernet_ctrl.clone().into();
238 let flexray_cc: CommunicationController = flexray_ctrl.clone().into();
239
240 let can_cluster = system.create_can_cluster("can_cluster", &package, None).unwrap();
241 let ethernet_cluster = system.create_ethernet_cluster("ethernet_cluster", &package).unwrap();
242 let flexray_cluster = system
243 .create_flexray_cluster("flexray_cluster", &package, &FlexrayClusterSettings::default())
244 .unwrap();
245
246 let can_channel = can_cluster.create_physical_channel("can_channel").unwrap();
247 let ethernet_channel = ethernet_cluster
248 .create_physical_channel("ethernet_channel", None)
249 .unwrap();
250 let flexray_channel = flexray_cluster
251 .create_physical_channel("flexray_channel", FlexrayChannelName::A)
252 .unwrap();
253
254 let can_connector = can_ctrl
255 .connect_physical_channel("can_connector", &can_channel)
256 .unwrap();
257 let ethernet_connector = ethernet_ctrl
258 .connect_physical_channel("ethernet_connector", ðernet_channel)
259 .unwrap();
260 let flexray_connector = flexray_ctrl
261 .connect_physical_channel("flexray_connector", &flexray_channel)
262 .unwrap();
263
264 let connector: CommunicationConnector = CommunicationConnector::Can(can_connector.clone());
265 assert_eq!(connector.controller().unwrap(), can_cc);
266 let connector = CommunicationConnector::Ethernet(ethernet_connector.clone());
267 assert_eq!(connector.controller().unwrap(), ethernet_cc);
268 let connector = CommunicationConnector::Flexray(flexray_connector.clone());
269 assert_eq!(connector.controller().unwrap(), flexray_cc);
270
271 assert_eq!(can_cc.element().item_name().unwrap(), "can");
272 assert_eq!(ethernet_cc.element().item_name().unwrap(), "ethernet");
273 assert_eq!(flexray_cc.element().item_name().unwrap(), "flexray");
274 }
275}