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 connected_channels(&self) -> impl Iterator<Item = FlexrayPhysicalChannel> + Send + 'static {
52 if let Ok(ecu) = self.ecu_instance().map(|ecuinstance| ecuinstance.element().clone()) {
53 FlexrayCtrlChannelsIterator::new(self, &ecu)
54 } else {
55 FlexrayCtrlChannelsIterator {
56 connector_iter: None,
57 comm_controller: self.0.clone(),
58 model: None,
59 }
60 }
61 }
62
63 pub fn connect_physical_channel(
93 &self,
94 connection_name: &str,
95 flx_channel: &FlexrayPhysicalChannel,
96 ) -> Result<FlexrayCommunicationConnector, AutosarAbstractionError> {
97 let ecu = self.0.named_parent()?.unwrap();
98
99 for existing_channel in self.connected_channels() {
100 if existing_channel == *flx_channel {
101 return Err(AutosarAbstractionError::ItemAlreadyExists);
102 }
103 }
104
105 let connectors = ecu.get_or_create_sub_element(ElementName::Connectors)?;
107 let connector = FlexrayCommunicationConnector::new(connection_name, &connectors, self)?;
108
109 let channel_connctor_refs = flx_channel
110 .element()
111 .get_or_create_sub_element(ElementName::CommConnectors)?;
112 channel_connctor_refs
113 .create_sub_element(ElementName::CommunicationConnectorRefConditional)
114 .and_then(|ccrc| ccrc.create_sub_element(ElementName::CommunicationConnectorRef))
115 .and_then(|ccr| ccr.set_reference_target(connector.element()))?;
116
117 Ok(connector)
118 }
119}
120
121impl AbstractCommunicationController for FlexrayCommunicationController {}
122
123#[derive(Debug, Clone, PartialEq, Eq, Hash)]
127pub struct FlexrayCommunicationConnector(Element);
128abstraction_element!(FlexrayCommunicationConnector, FlexrayCommunicationConnector);
129impl IdentifiableAbstractionElement for FlexrayCommunicationConnector {}
130
131impl FlexrayCommunicationConnector {
132 pub(crate) fn new(
133 name: &str,
134 parent: &Element,
135 controller: &FlexrayCommunicationController,
136 ) -> Result<Self, AutosarAbstractionError> {
137 let connector = parent.create_named_sub_element(ElementName::FlexrayCommunicationConnector, name)?;
138 connector
139 .create_sub_element(ElementName::CommControllerRef)
140 .and_then(|refelem| refelem.set_reference_target(controller.element()))?;
141
142 Ok(Self(connector))
143 }
144}
145
146impl AbstractCommunicationConnector for FlexrayCommunicationConnector {
147 type CommunicationControllerType = FlexrayCommunicationController;
148
149 fn controller(&self) -> Result<Self::CommunicationControllerType, AutosarAbstractionError> {
150 let controller = self
151 .element()
152 .get_sub_element(ElementName::CommControllerRef)
153 .ok_or_else(|| {
154 AutosarAbstractionError::ModelError(AutosarDataError::ElementNotFound {
155 target: ElementName::CommControllerRef,
156 parent: self.element().element_name(),
157 })
158 })?
159 .get_reference_target()?;
160 FlexrayCommunicationController::try_from(controller)
161 }
162}
163
164#[doc(hidden)]
167pub struct FlexrayCtrlChannelsIterator {
168 connector_iter: Option<ElementsIterator>,
169 comm_controller: Element,
170 model: Option<AutosarModel>,
171}
172
173impl FlexrayCtrlChannelsIterator {
174 fn new(controller: &FlexrayCommunicationController, ecu: &Element) -> Self {
175 let iter = ecu.get_sub_element(ElementName::Connectors).map(|c| c.sub_elements());
176 let comm_controller = controller.element().clone();
177 let model = comm_controller.model().ok();
178 Self {
179 connector_iter: iter,
180 comm_controller,
181 model,
182 }
183 }
184}
185
186impl Iterator for FlexrayCtrlChannelsIterator {
187 type Item = FlexrayPhysicalChannel;
188
189 fn next(&mut self) -> Option<Self::Item> {
190 let model = self.model.as_ref()?;
191 let connector_iter = self.connector_iter.as_mut()?;
192 for connector in connector_iter.by_ref() {
193 if connector.element_name() == ElementName::FlexrayCommunicationConnector {
194 if let Some(commcontroller_of_connector) = connector
195 .get_sub_element(ElementName::CommControllerRef)
196 .and_then(|ccr| ccr.get_reference_target().ok())
197 {
198 if commcontroller_of_connector == self.comm_controller {
199 for ref_origin in model
200 .get_references_to(&connector.path().ok()?)
201 .iter()
202 .filter_map(WeakElement::upgrade)
203 .filter_map(|elem| elem.named_parent().ok().flatten())
204 {
205 if ref_origin.element_name() == ElementName::FlexrayPhysicalChannel {
208 return FlexrayPhysicalChannel::try_from(ref_origin).ok();
209 }
210 }
211 }
212 }
213 }
214 }
215 None
216 }
217}
218
219#[cfg(test)]
222mod test {
223 use crate::{
224 AutosarModelAbstraction, SystemCategory,
225 communication::{FlexrayChannelName, FlexrayClusterSettings},
226 };
227
228 use super::*;
229 use autosar_data::AutosarVersion;
230
231 #[test]
232 fn controller() {
233 let model = AutosarModelAbstraction::create("filename", AutosarVersion::Autosar_00048);
234 let pkg = model.get_or_create_package("/test").unwrap();
235 let system = pkg.create_system("System", SystemCategory::SystemDescription).unwrap();
236 let ecu = system.create_ecu_instance("ECU", &pkg).unwrap();
237
238 let result = ecu.create_flexray_communication_controller("Controller");
240 let controller = result.unwrap();
241
242 let settings = FlexrayClusterSettings::default();
244 let cluster = system.create_flexray_cluster("FlxCluster", &pkg, &settings).unwrap();
245 let channel1 = cluster.create_physical_channel("C1", FlexrayChannelName::A).unwrap();
246
247 let connector = controller
249 .connect_physical_channel("connection_name1", &channel1)
250 .unwrap();
251 assert_eq!(connector.controller().unwrap(), controller);
252 let result = controller.connect_physical_channel("connection_name2", &channel1);
254 assert!(result.is_err());
255
256 let count = controller.connected_channels().count();
257 assert_eq!(count, 1);
258
259 let ctrl_parent = controller.0.parent().unwrap().unwrap();
261 ctrl_parent.remove_sub_element(controller.0.clone()).unwrap();
262 let count = controller.connected_channels().count();
263 assert_eq!(count, 0);
264 }
265
266 #[test]
267 fn connector() {
268 let model = AutosarModelAbstraction::create("filename", AutosarVersion::Autosar_00048);
269 let pkg = model.get_or_create_package("/test").unwrap();
270 let system = pkg.create_system("System", SystemCategory::SystemDescription).unwrap();
271 let ecu = system.create_ecu_instance("ECU", &pkg).unwrap();
272
273 let controller = ecu.create_flexray_communication_controller("Controller").unwrap();
275 assert_eq!(controller.ecu_instance().unwrap(), ecu);
276
277 let settings = FlexrayClusterSettings::default();
279 let cluster = system.create_flexray_cluster("FlxCluster", &pkg, &settings).unwrap();
280 let channel1 = cluster.create_physical_channel("C1", FlexrayChannelName::A).unwrap();
281
282 let connector = controller
284 .connect_physical_channel("connection_name1", &channel1)
285 .unwrap();
286 assert_eq!(connector.controller().unwrap(), controller);
287 assert_eq!(connector.ecu_instance().unwrap(), ecu);
288
289 let conn_parent = connector.0.parent().unwrap().unwrap();
291 conn_parent.remove_sub_element(connector.0.clone()).unwrap();
292 let result = connector.controller();
293 assert!(result.is_err());
294 }
295}