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
99impl CommunicationController {
100 pub fn remove(self, deep: bool) -> Result<(), AutosarAbstractionError> {
102 match self {
103 CommunicationController::Can(can_ctrl) => can_ctrl.remove(deep),
104 CommunicationController::Ethernet(eth_ctrl) => eth_ctrl.remove(deep),
105 CommunicationController::Flexray(flx_ctrl) => flx_ctrl.remove(deep),
106 CommunicationController::LinMaster(lin_master) => lin_master.remove(deep),
107 CommunicationController::LinSlave(lin_slave) => lin_slave.remove(deep),
108 }
109 }
110}
111
112pub trait AbstractCommunicationController: AbstractionElement {
116 fn ecu_instance(&self) -> Result<EcuInstance, AutosarAbstractionError> {
137 self.element().named_parent()?.unwrap().try_into()
141 }
142}
143
144pub trait AbstractCommunicationConnector: AbstractionElement {
148 type CommunicationControllerType: AbstractCommunicationController;
150
151 fn ecu_instance(&self) -> Result<EcuInstance, AutosarAbstractionError> {
153 self.element().named_parent()?.unwrap().try_into()
157 }
158
159 fn controller(&self) -> Result<Self::CommunicationControllerType, AutosarAbstractionError>;
161}
162
163#[derive(Debug, Clone, PartialEq, Eq)]
167pub enum CommunicationConnector {
168 Can(CanCommunicationConnector),
170 Ethernet(EthernetCommunicationConnector),
172 Flexray(FlexrayCommunicationConnector),
174 Lin(LinCommunicationConnector),
176}
177
178impl AbstractionElement for CommunicationConnector {
179 fn element(&self) -> &autosar_data::Element {
180 match self {
181 CommunicationConnector::Can(cc) => cc.element(),
182 CommunicationConnector::Ethernet(ec) => ec.element(),
183 CommunicationConnector::Flexray(fc) => fc.element(),
184 CommunicationConnector::Lin(lc) => lc.element(),
185 }
186 }
187}
188
189impl TryFrom<Element> for CommunicationConnector {
190 type Error = AutosarAbstractionError;
191
192 fn try_from(element: Element) -> Result<Self, Self::Error> {
193 match element.element_name() {
194 ElementName::CanCommunicationConnector => Ok(Self::Can(CanCommunicationConnector::try_from(element)?)),
195 ElementName::EthernetCommunicationConnector => {
196 Ok(Self::Ethernet(EthernetCommunicationConnector::try_from(element)?))
197 }
198 ElementName::FlexrayCommunicationConnector => {
199 Ok(Self::Flexray(FlexrayCommunicationConnector::try_from(element)?))
200 }
201 ElementName::LinCommunicationConnector => Ok(Self::Lin(LinCommunicationConnector::try_from(element)?)),
202 _ => Err(AutosarAbstractionError::ConversionError {
203 element,
204 dest: "CommunicationConnector".to_string(),
205 }),
206 }
207 }
208}
209
210impl IdentifiableAbstractionElement for CommunicationConnector {}
211
212impl AbstractCommunicationConnector for CommunicationConnector {
213 type CommunicationControllerType = CommunicationController;
214
215 fn controller(&self) -> Result<Self::CommunicationControllerType, AutosarAbstractionError> {
216 let Some(controller_ref) = self.element().get_sub_element(ElementName::CommControllerRef) else {
217 return Err(AutosarAbstractionError::ModelError(AutosarDataError::ElementNotFound {
218 target: ElementName::CommControllerRef,
219 parent: self.element().element_name(),
220 }));
221 };
222 let controller = controller_ref.get_reference_target()?;
223 Self::CommunicationControllerType::try_from(controller)
224 }
225}
226
227#[cfg(test)]
230mod tests {
231 use super::*;
232 use crate::{
233 AutosarModelAbstraction, SystemCategory,
234 communication::{FlexrayChannelName, FlexrayClusterSettings},
235 };
236 use autosar_data::AutosarVersion;
237
238 #[test]
239 fn test_communication_controller() {
240 let model = AutosarModelAbstraction::create("filename", AutosarVersion::LATEST);
241 let package = model.get_or_create_package("/test").unwrap();
242 let system = package.create_system("System", SystemCategory::SystemExtract).unwrap();
243
244 let ecu = system.create_ecu_instance("ecu", &package).unwrap();
245 let can_ctrl = ecu.create_can_communication_controller("can").unwrap();
246 let ethernet_ctrl = ecu.create_ethernet_communication_controller("ethernet", None).unwrap();
247 let flexray_ctrl = ecu.create_flexray_communication_controller("flexray").unwrap();
248 let lin_master_ctrl = ecu.create_lin_master_communication_controller("lin_master").unwrap();
249 let lin_slave_ctrl = ecu.create_lin_slave_communication_controller("lin_slave").unwrap();
250
251 let can_cc: CommunicationController = can_ctrl.clone().into();
252 let ethernet_cc: CommunicationController = ethernet_ctrl.clone().into();
253 let flexray_cc: CommunicationController = flexray_ctrl.clone().into();
254 let lin_master_cc: CommunicationController = lin_master_ctrl.clone().into();
255 let lin_slave_cc: CommunicationController = lin_slave_ctrl.clone().into();
256
257 let can_cluster = system.create_can_cluster("can_cluster", &package, None).unwrap();
258 let ethernet_cluster = system.create_ethernet_cluster("ethernet_cluster", &package).unwrap();
259 let flexray_cluster = system
260 .create_flexray_cluster("flexray_cluster", &package, &FlexrayClusterSettings::default())
261 .unwrap();
262 let lin_cluster = system.create_lin_cluster("lin_cluster", &package).unwrap();
263
264 let can_channel = can_cluster.create_physical_channel("can_channel").unwrap();
265 let ethernet_channel = ethernet_cluster
266 .create_physical_channel("ethernet_channel", None)
267 .unwrap();
268 let flexray_channel = flexray_cluster
269 .create_physical_channel("flexray_channel", FlexrayChannelName::A)
270 .unwrap();
271 let lin_channel = lin_cluster.create_physical_channel("lin_channel").unwrap();
272
273 let can_connector = can_ctrl
274 .connect_physical_channel("can_connector", &can_channel)
275 .unwrap();
276 let ethernet_connector = ethernet_ctrl
277 .connect_physical_channel("ethernet_connector", ðernet_channel)
278 .unwrap();
279 let flexray_connector = flexray_ctrl
280 .connect_physical_channel("flexray_connector", &flexray_channel)
281 .unwrap();
282 let lin_connector = lin_master_ctrl
283 .connect_physical_channel("lin_connector", &lin_channel)
284 .unwrap();
285 let lin_slave_connector = lin_slave_ctrl
286 .connect_physical_channel("lin_slave_connector", &lin_channel)
287 .unwrap();
288
289 let connector: CommunicationConnector = CommunicationConnector::Can(can_connector.clone());
290 assert_eq!(connector.controller().unwrap(), can_cc);
291 let connector = CommunicationConnector::Ethernet(ethernet_connector.clone());
292 assert_eq!(connector.controller().unwrap(), ethernet_cc);
293 let connector = CommunicationConnector::Flexray(flexray_connector.clone());
294 assert_eq!(connector.controller().unwrap(), flexray_cc);
295 let connector = CommunicationConnector::Lin(lin_connector.clone());
296 assert_eq!(connector.controller().unwrap(), lin_master_cc);
297 let connector = CommunicationConnector::Lin(lin_slave_connector.clone());
298 assert_eq!(connector.controller().unwrap(), lin_slave_cc);
299
300 assert_eq!(can_cc.element().item_name().unwrap(), "can");
301 assert_eq!(ethernet_cc.element().item_name().unwrap(), "ethernet");
302 assert_eq!(flexray_cc.element().item_name().unwrap(), "flexray");
303 assert_eq!(lin_master_cc.element().item_name().unwrap(), "lin_master");
304 assert_eq!(lin_slave_cc.element().item_name().unwrap(), "lin_slave");
305
306 assert_eq!(ecu.communication_controllers().count(), 5);
307 can_cc.remove(true).unwrap();
308 ethernet_cc.remove(true).unwrap();
309 flexray_cc.remove(true).unwrap();
310 lin_master_cc.remove(true).unwrap();
311 lin_slave_cc.remove(true).unwrap();
312 assert_eq!(ecu.communication_controllers().count(), 0);
313 }
314}