autosar_data_abstraction/communication/controller/
flexray.rs1use crate::communication::{AbstractCommunicationConnector, AbstractCommunicationController, FlexrayPhysicalChannel};
2use crate::{
3 AbstractionElement, AutosarAbstractionError, EcuInstance, IdentifiableAbstractionElement, abstraction_element,
4};
5use autosar_data::{AutosarDataError, AutosarModel, Element, ElementName, ElementsIterator, WeakElement};
6
7#[derive(Debug, Clone, PartialEq, Eq, Hash)]
9pub struct FlexrayCommunicationController(Element);
10abstraction_element!(FlexrayCommunicationController, FlexrayCommunicationController);
11impl IdentifiableAbstractionElement for FlexrayCommunicationController {}
12
13impl FlexrayCommunicationController {
14 pub(crate) fn new(name: &str, ecu: &EcuInstance) -> Result<Self, AutosarAbstractionError> {
16 let commcontrollers = ecu.element().get_or_create_sub_element(ElementName::CommControllers)?;
17 let ctrl = commcontrollers.create_named_sub_element(ElementName::FlexrayCommunicationController, name)?;
18 let _flxccc = ctrl
19 .create_sub_element(ElementName::FlexrayCommunicationControllerVariants)?
20 .create_sub_element(ElementName::FlexrayCommunicationControllerConditional)?;
21
22 Ok(Self(ctrl))
23 }
24
25 pub fn remove(self, deep: bool) -> Result<(), AutosarAbstractionError> {
27 let ecu_instance = self.ecu_instance()?;
29 for connector in ecu_instance
30 .element()
31 .get_sub_element(ElementName::Connectors)
32 .iter()
33 .flat_map(|connectors| connectors.sub_elements())
34 .filter_map(|conn| FlexrayCommunicationConnector::try_from(conn).ok())
35 {
36 if let Ok(controller_of_connector) = connector.controller()
37 && controller_of_connector == self
38 {
39 connector.remove(deep)?;
40 }
41 }
42
43 AbstractionElement::remove(self, deep)
44 }
45
46 pub fn connected_channels(&self) -> impl Iterator<Item = FlexrayPhysicalChannel> + Send + use<> {
73 if let Ok(ecu) = self.ecu_instance().map(|ecuinstance| ecuinstance.element().clone()) {
74 FlexrayCtrlChannelsIterator::new(self, &ecu)
75 } else {
76 FlexrayCtrlChannelsIterator {
77 connector_iter: None,
78 comm_controller: self.0.clone(),
79 model: None,
80 }
81 }
82 }
83
84 pub fn connect_physical_channel(
114 &self,
115 connection_name: &str,
116 flx_channel: &FlexrayPhysicalChannel,
117 ) -> Result<FlexrayCommunicationConnector, AutosarAbstractionError> {
118 let ecu = self.0.named_parent()?.unwrap();
119
120 for existing_channel in self.connected_channels() {
121 if existing_channel == *flx_channel {
122 return Err(AutosarAbstractionError::ItemAlreadyExists);
123 }
124 }
125
126 let connectors = ecu.get_or_create_sub_element(ElementName::Connectors)?;
128 let connector = FlexrayCommunicationConnector::new(connection_name, &connectors, self)?;
129
130 let channel_connctor_refs = flx_channel
131 .element()
132 .get_or_create_sub_element(ElementName::CommConnectors)?;
133 channel_connctor_refs
134 .create_sub_element(ElementName::CommunicationConnectorRefConditional)
135 .and_then(|ccrc| ccrc.create_sub_element(ElementName::CommunicationConnectorRef))
136 .and_then(|ccr| ccr.set_reference_target(connector.element()))?;
137
138 Ok(connector)
139 }
140}
141
142impl AbstractCommunicationController for FlexrayCommunicationController {}
143
144#[derive(Debug, Clone, PartialEq, Eq, Hash)]
148pub struct FlexrayCommunicationConnector(Element);
149abstraction_element!(FlexrayCommunicationConnector, FlexrayCommunicationConnector);
150impl IdentifiableAbstractionElement for FlexrayCommunicationConnector {}
151
152impl FlexrayCommunicationConnector {
153 pub(crate) fn new(
154 name: &str,
155 parent: &Element,
156 controller: &FlexrayCommunicationController,
157 ) -> Result<Self, AutosarAbstractionError> {
158 let connector = parent.create_named_sub_element(ElementName::FlexrayCommunicationConnector, name)?;
159 connector
160 .create_sub_element(ElementName::CommControllerRef)
161 .and_then(|refelem| refelem.set_reference_target(controller.element()))?;
162
163 Ok(Self(connector))
164 }
165}
166
167impl AbstractCommunicationConnector for FlexrayCommunicationConnector {
168 type CommunicationControllerType = FlexrayCommunicationController;
169
170 fn controller(&self) -> Result<Self::CommunicationControllerType, AutosarAbstractionError> {
171 let controller = self
172 .element()
173 .get_sub_element(ElementName::CommControllerRef)
174 .ok_or_else(|| {
175 AutosarAbstractionError::ModelError(AutosarDataError::ElementNotFound {
176 target: ElementName::CommControllerRef,
177 parent: self.element().element_name(),
178 })
179 })?
180 .get_reference_target()?;
181 FlexrayCommunicationController::try_from(controller)
182 }
183}
184
185#[doc(hidden)]
188pub struct FlexrayCtrlChannelsIterator {
189 connector_iter: Option<ElementsIterator>,
190 comm_controller: Element,
191 model: Option<AutosarModel>,
192}
193
194impl FlexrayCtrlChannelsIterator {
195 fn new(controller: &FlexrayCommunicationController, ecu: &Element) -> Self {
196 let iter = ecu.get_sub_element(ElementName::Connectors).map(|c| c.sub_elements());
197 let comm_controller = controller.element().clone();
198 let model = comm_controller.model().ok();
199 Self {
200 connector_iter: iter,
201 comm_controller,
202 model,
203 }
204 }
205}
206
207impl Iterator for FlexrayCtrlChannelsIterator {
208 type Item = FlexrayPhysicalChannel;
209
210 fn next(&mut self) -> Option<Self::Item> {
211 let model = self.model.as_ref()?;
212 let connector_iter = self.connector_iter.as_mut()?;
213 for connector in connector_iter.by_ref() {
214 if connector.element_name() == ElementName::FlexrayCommunicationConnector
215 && let Some(commcontroller_of_connector) = connector
216 .get_sub_element(ElementName::CommControllerRef)
217 .and_then(|ccr| ccr.get_reference_target().ok())
218 && commcontroller_of_connector == self.comm_controller
219 {
220 for ref_origin in model
221 .get_references_to(&connector.path().ok()?)
222 .iter()
223 .filter_map(WeakElement::upgrade)
224 .filter_map(|elem| elem.named_parent().ok().flatten())
225 {
226 if ref_origin.element_name() == ElementName::FlexrayPhysicalChannel {
229 return FlexrayPhysicalChannel::try_from(ref_origin).ok();
230 }
231 }
232 }
233 }
234 None
235 }
236}
237
238#[cfg(test)]
241mod test {
242 use crate::{
243 AutosarModelAbstraction, SystemCategory,
244 communication::{FlexrayChannelName, FlexrayClusterSettings},
245 };
246
247 use super::*;
248 use autosar_data::AutosarVersion;
249
250 #[test]
251 fn controller() {
252 let model = AutosarModelAbstraction::create("filename", AutosarVersion::Autosar_00048);
253 let pkg = model.get_or_create_package("/test").unwrap();
254 let system = pkg.create_system("System", SystemCategory::SystemDescription).unwrap();
255 let ecu = system.create_ecu_instance("ECU", &pkg).unwrap();
256
257 let result = ecu.create_flexray_communication_controller("Controller");
259 let controller = result.unwrap();
260
261 let settings = FlexrayClusterSettings::default();
263 let cluster = system.create_flexray_cluster("FlxCluster", &pkg, &settings).unwrap();
264 let channel1 = cluster.create_physical_channel("C1", FlexrayChannelName::A).unwrap();
265
266 let connector = controller
268 .connect_physical_channel("connection_name1", &channel1)
269 .unwrap();
270 assert_eq!(connector.controller().unwrap(), controller);
271 let result = controller.connect_physical_channel("connection_name2", &channel1);
273 assert!(result.is_err());
274
275 let count = controller.connected_channels().count();
276 assert_eq!(count, 1);
277
278 let ctrl_parent = controller.0.parent().unwrap().unwrap();
280 ctrl_parent.remove_sub_element(controller.0.clone()).unwrap();
281 let count = controller.connected_channels().count();
282 assert_eq!(count, 0);
283 }
284
285 #[test]
286 fn connector() {
287 let model = AutosarModelAbstraction::create("filename", AutosarVersion::Autosar_00048);
288 let pkg = model.get_or_create_package("/test").unwrap();
289 let system = pkg.create_system("System", SystemCategory::SystemDescription).unwrap();
290 let ecu = system.create_ecu_instance("ECU", &pkg).unwrap();
291
292 let controller = ecu.create_flexray_communication_controller("Controller").unwrap();
294 assert_eq!(controller.ecu_instance().unwrap(), ecu);
295
296 let settings = FlexrayClusterSettings::default();
298 let cluster = system.create_flexray_cluster("FlxCluster", &pkg, &settings).unwrap();
299 let channel1 = cluster.create_physical_channel("C1", FlexrayChannelName::A).unwrap();
300
301 let connector = controller
303 .connect_physical_channel("connection_name1", &channel1)
304 .unwrap();
305 assert_eq!(connector.controller().unwrap(), controller);
306 assert_eq!(connector.ecu_instance().unwrap(), ecu);
307
308 let conn_parent = connector.0.parent().unwrap().unwrap();
310 conn_parent.remove_sub_element(connector.0.clone()).unwrap();
311 let result = connector.controller();
312 assert!(result.is_err());
313 }
314
315 #[test]
316 fn remove_controller() {
317 let model = AutosarModelAbstraction::create("filename", AutosarVersion::Autosar_00048);
318 let pkg = model.get_or_create_package("/test").unwrap();
319 let system = pkg.create_system("System", SystemCategory::SystemDescription).unwrap();
320 let ecu = system.create_ecu_instance("ECU", &pkg).unwrap();
321 let controller = ecu.create_flexray_communication_controller("Controller").unwrap();
323 let cluster = system
324 .create_flexray_cluster("FlxCluster", &pkg, &FlexrayClusterSettings::default())
325 .unwrap();
326 let channel_a = cluster.create_physical_channel("C1", FlexrayChannelName::A).unwrap();
327 let connector = controller
328 .connect_physical_channel("connection_name1", &channel_a)
329 .unwrap();
330
331 controller.remove(true).unwrap();
333
334 assert_eq!(ecu.communication_controllers().count(), 0);
335 assert!(connector.element().path().is_err());
336 }
337}