1use crate::communication::{AbstractIpdu, FlexrayCluster, FlexrayCommunicationConnector, IPdu, NPdu, TpAddress};
2use crate::{
3 AbstractionElement, ArPackage, AutosarAbstractionError, EcuInstance, IdentifiableAbstractionElement,
4 abstraction_element,
5};
6use autosar_data::{Element, ElementName};
7
8#[derive(Debug, Clone, PartialEq, Eq, Hash)]
10pub struct FlexrayTpConfig(Element);
11abstraction_element!(FlexrayTpConfig, FlexrayTpConfig);
12impl IdentifiableAbstractionElement for FlexrayTpConfig {}
13
14impl FlexrayTpConfig {
15 pub(crate) fn new(
16 name: &str,
17 package: &ArPackage,
18 cluster: &FlexrayCluster,
19 ) -> Result<Self, AutosarAbstractionError> {
20 let pkg_elem = package.element().get_or_create_sub_element(ElementName::Elements)?;
21
22 let tp_config_elem = pkg_elem.create_named_sub_element(ElementName::FlexrayTpConfig, name)?;
23 let tp_config = Self(tp_config_elem);
24 tp_config.set_cluster(cluster)?;
25
26 Ok(tp_config)
27 }
28
29 pub fn set_cluster(&self, cluster: &FlexrayCluster) -> Result<(), AutosarAbstractionError> {
31 self.element()
32 .get_or_create_sub_element(ElementName::CommunicationClusterRef)?
33 .set_reference_target(cluster.element())?;
34 Ok(())
35 }
36
37 #[must_use]
39 pub fn cluster(&self) -> Option<FlexrayCluster> {
40 self.element()
41 .get_sub_element(ElementName::CommunicationClusterRef)
42 .and_then(|elem| elem.get_reference_target().ok())
43 .and_then(|elem| elem.try_into().ok())
44 }
45
46 pub fn create_flexray_tp_pdu_pool(&self, name: &str) -> Result<FlexrayTpPduPool, AutosarAbstractionError> {
48 let pdu_pools_elem = self.element().get_or_create_sub_element(ElementName::PduPools)?;
49 FlexrayTpPduPool::new(name, &pdu_pools_elem)
50 }
51
52 pub fn flexray_tp_pdu_pools(&self) -> impl Iterator<Item = FlexrayTpPduPool> + Send + use<> {
54 self.element()
55 .get_sub_element(ElementName::PduPools)
56 .into_iter()
57 .flat_map(|elem| elem.sub_elements())
58 .map(FlexrayTpPduPool)
59 }
60
61 pub fn create_tp_address(&self, name: &str, address: u32) -> Result<TpAddress, AutosarAbstractionError> {
63 let tp_addresses_elem = self.element().get_or_create_sub_element(ElementName::TpAddresss)?;
64 TpAddress::new(name, &tp_addresses_elem, address)
65 }
66
67 pub fn tp_addresses(&self) -> impl Iterator<Item = TpAddress> + Send + use<> {
69 self.element()
70 .get_sub_element(ElementName::TpAddresss)
71 .into_iter()
72 .flat_map(|elem| elem.sub_elements())
73 .filter_map(|elem| elem.try_into().ok())
74 }
75
76 pub fn create_flexray_tp_connection<T: AbstractIpdu>(
78 &self,
79 name: Option<&str>,
80 transmitter: &FlexrayTpNode,
81 direct_tp_sdu: &T,
82 connection_control: &FlexrayTpConnectionControl,
83 ) -> Result<FlexrayTpConnection, AutosarAbstractionError> {
84 let tp_connections_elem = self.element().get_or_create_sub_element(ElementName::TpConnections)?;
85 FlexrayTpConnection::new(
86 name,
87 &tp_connections_elem,
88 transmitter,
89 &direct_tp_sdu.clone().into(),
90 connection_control,
91 )
92 }
93
94 pub fn flexray_tp_connections(&self) -> impl Iterator<Item = FlexrayTpConnection> + Send + use<> {
96 self.element()
97 .get_sub_element(ElementName::TpConnections)
98 .into_iter()
99 .flat_map(|elem| elem.sub_elements())
100 .map(FlexrayTpConnection)
101 }
102
103 pub fn create_flexray_tp_connection_control(
105 &self,
106 name: &str,
107 ) -> Result<FlexrayTpConnectionControl, AutosarAbstractionError> {
108 let connection_controls_elem = self
109 .element()
110 .get_or_create_sub_element(ElementName::TpConnectionControls)?;
111 FlexrayTpConnectionControl::new(name, &connection_controls_elem)
112 }
113
114 pub fn flexray_tp_connection_controls(&self) -> impl Iterator<Item = FlexrayTpConnectionControl> + Send + use<> {
116 self.element()
117 .get_sub_element(ElementName::TpConnectionControls)
118 .into_iter()
119 .flat_map(|elem| elem.sub_elements())
120 .map(FlexrayTpConnectionControl)
121 }
122
123 pub fn create_flexray_tp_ecu(
125 &self,
126 ecu_instance: &EcuInstance,
127 full_duplex_enabled: bool,
128 ) -> Result<FlexrayTpEcu, AutosarAbstractionError> {
129 let ecu_collection = self.element().get_or_create_sub_element(ElementName::TpEcus)?;
130 FlexrayTpEcu::new(&ecu_collection, ecu_instance, full_duplex_enabled)
131 }
132
133 pub fn flexray_tp_ecus(&self) -> impl Iterator<Item = FlexrayTpEcu> + Send + use<> {
135 self.element()
136 .get_sub_element(ElementName::TpEcus)
137 .into_iter()
138 .flat_map(|elem| elem.sub_elements())
139 .filter_map(|elem| FlexrayTpEcu::try_from(elem).ok())
140 }
141
142 pub fn create_flexray_tp_node(&self, name: &str) -> Result<FlexrayTpNode, AutosarAbstractionError> {
144 let nodes_elem = self.element().get_or_create_sub_element(ElementName::TpNodes)?;
145 FlexrayTpNode::new(name, &nodes_elem)
146 }
147
148 pub fn flexray_tp_nodes(&self) -> impl Iterator<Item = FlexrayTpNode> + Send + use<> {
150 self.element()
151 .get_sub_element(ElementName::TpNodes)
152 .into_iter()
153 .flat_map(|elem| elem.sub_elements())
154 .map(FlexrayTpNode)
155 }
156}
157
158#[derive(Debug, Clone, PartialEq, Eq, Hash)]
162pub struct FlexrayTpPduPool(Element);
163abstraction_element!(FlexrayTpPduPool, FlexrayTpPduPool);
164impl IdentifiableAbstractionElement for FlexrayTpPduPool {}
165
166impl FlexrayTpPduPool {
167 pub(crate) fn new(name: &str, parent: &Element) -> Result<Self, AutosarAbstractionError> {
168 let pdu_pool_elem = parent.create_named_sub_element(ElementName::FlexrayTpPduPool, name)?;
169 Ok(Self(pdu_pool_elem))
170 }
171
172 pub fn add_n_pdu(&self, n_pdu: &NPdu) -> Result<(), AutosarAbstractionError> {
174 self.element()
175 .get_or_create_sub_element(ElementName::NPduRefs)?
176 .create_sub_element(ElementName::NPduRef)?
177 .set_reference_target(n_pdu.element())?;
178 Ok(())
179 }
180
181 pub fn n_pdus(&self) -> impl Iterator<Item = NPdu> + Send + use<> {
183 self.element()
184 .get_sub_element(ElementName::NPduRefs)
185 .into_iter()
186 .flat_map(|elem| elem.sub_elements())
187 .filter_map(|ref_elem| {
188 ref_elem
189 .get_reference_target()
190 .ok()
191 .and_then(|elem| elem.try_into().ok())
192 })
193 }
194}
195
196#[derive(Debug, Clone, PartialEq, Eq, Hash)]
200pub struct FlexrayTpConnection(Element);
201abstraction_element!(FlexrayTpConnection, FlexrayTpConnection);
202
203impl IdentifiableAbstractionElement for FlexrayTpConnection {
204 fn name(&self) -> Option<String> {
210 self.element()
211 .get_sub_element(ElementName::Ident)
212 .and_then(|elem| elem.item_name())
213 }
214
215 fn set_name(&self, name: &str) -> Result<(), AutosarAbstractionError> {
217 if let Some(ident_elem) = self.element().get_sub_element(ElementName::Ident) {
218 ident_elem.set_item_name(name)?;
219 } else {
220 self.element().create_named_sub_element(ElementName::Ident, name)?;
221 }
222 Ok(())
223 }
224}
225
226impl FlexrayTpConnection {
227 pub(crate) fn new(
228 name: Option<&str>,
229 parent: &Element,
230 transmitter: &FlexrayTpNode,
231 direct_tp_sdu: &IPdu,
232 connection_control: &FlexrayTpConnectionControl,
233 ) -> Result<Self, AutosarAbstractionError> {
234 let tp_connection_elem = parent.create_sub_element(ElementName::FlexrayTpConnection)?;
235 if let Some(name) = name {
236 tp_connection_elem.create_named_sub_element(ElementName::Ident, name)?;
237 }
238 let tp_connection = Self(tp_connection_elem);
239 tp_connection.set_transmitter(transmitter)?;
240 tp_connection.set_direct_tp_sdu(direct_tp_sdu)?;
241 tp_connection.set_connection_control(connection_control)?;
242
243 Ok(tp_connection)
244 }
245
246 pub fn set_transmitter(&self, transmitter: &FlexrayTpNode) -> Result<(), AutosarAbstractionError> {
248 self.element()
249 .get_or_create_sub_element(ElementName::TransmitterRef)?
250 .set_reference_target(transmitter.element())?;
251 Ok(())
252 }
253
254 #[must_use]
256 pub fn transmitter(&self) -> Option<FlexrayTpNode> {
257 self.element()
258 .get_sub_element(ElementName::TransmitterRef)
259 .and_then(|elem| elem.get_reference_target().ok())
260 .and_then(|elem| elem.try_into().ok())
261 }
262
263 pub fn set_direct_tp_sdu<T: AbstractIpdu>(&self, direct_tp_sdu: &T) -> Result<(), AutosarAbstractionError> {
265 self.element()
266 .get_or_create_sub_element(ElementName::DirectTpSduRef)?
267 .set_reference_target(direct_tp_sdu.element())?;
268 Ok(())
269 }
270
271 #[must_use]
273 pub fn direct_tp_sdu(&self) -> Option<IPdu> {
274 self.element()
275 .get_sub_element(ElementName::DirectTpSduRef)
276 .and_then(|elem| elem.get_reference_target().ok())
277 .and_then(|elem| elem.try_into().ok())
278 }
279
280 pub fn set_connection_control(
282 &self,
283 connection_control: &FlexrayTpConnectionControl,
284 ) -> Result<(), AutosarAbstractionError> {
285 self.element()
286 .get_or_create_sub_element(ElementName::TpConnectionControlRef)?
287 .set_reference_target(connection_control.element())?;
288 Ok(())
289 }
290
291 #[must_use]
293 pub fn connection_control(&self) -> Option<FlexrayTpConnectionControl> {
294 self.element()
295 .get_sub_element(ElementName::TpConnectionControlRef)?
296 .get_reference_target()
297 .ok()?
298 .try_into()
299 .ok()
300 }
301
302 pub fn add_receiver(&self, receiver: &FlexrayTpNode) -> Result<(), AutosarAbstractionError> {
304 self.element()
305 .get_or_create_sub_element(ElementName::ReceiverRefs)?
306 .create_sub_element(ElementName::ReceiverRef)?
307 .set_reference_target(receiver.element())?;
308 Ok(())
309 }
310
311 pub fn receivers(&self) -> impl Iterator<Item = FlexrayTpNode> + Send + use<> {
313 self.element()
314 .get_sub_element(ElementName::ReceiverRefs)
315 .into_iter()
316 .flat_map(|elem| elem.sub_elements())
317 .filter_map(|ref_elem| {
318 ref_elem
319 .get_reference_target()
320 .ok()
321 .and_then(|elem| elem.try_into().ok())
322 })
323 }
324
325 pub fn set_reversed_tp_sdu<T: AbstractIpdu>(&self, reversed_tp_sdu: &T) -> Result<(), AutosarAbstractionError> {
328 self.element()
329 .get_or_create_sub_element(ElementName::ReversedTpSduRef)?
330 .set_reference_target(reversed_tp_sdu.element())?;
331 Ok(())
332 }
333
334 #[must_use]
336 pub fn reversed_tp_sdu(&self) -> Option<IPdu> {
337 self.element()
338 .get_sub_element(ElementName::ReversedTpSduRef)
339 .and_then(|elem| elem.get_reference_target().ok())
340 .and_then(|elem| elem.try_into().ok())
341 }
342
343 pub fn set_tx_pdu_pool(&self, tx_pdu_pool: &FlexrayTpPduPool) -> Result<(), AutosarAbstractionError> {
345 self.element()
346 .get_or_create_sub_element(ElementName::TxPduPoolRef)?
347 .set_reference_target(tx_pdu_pool.element())?;
348 Ok(())
349 }
350
351 #[must_use]
353 pub fn tx_pdu_pool(&self) -> Option<FlexrayTpPduPool> {
354 self.element()
355 .get_sub_element(ElementName::TxPduPoolRef)
356 .and_then(|elem| elem.get_reference_target().ok())
357 .and_then(|elem| elem.try_into().ok())
358 }
359
360 pub fn set_rx_pdu_pool(&self, rx_pdu_pool: &FlexrayTpPduPool) -> Result<(), AutosarAbstractionError> {
362 self.element()
363 .get_or_create_sub_element(ElementName::RxPduPoolRef)?
364 .set_reference_target(rx_pdu_pool.element())?;
365 Ok(())
366 }
367
368 #[must_use]
370 pub fn rx_pdu_pool(&self) -> Option<FlexrayTpPduPool> {
371 self.element()
372 .get_sub_element(ElementName::RxPduPoolRef)
373 .and_then(|elem| elem.get_reference_target().ok())
374 .and_then(|elem| elem.try_into().ok())
375 }
376
377 pub fn set_multicast_address(&self, multicast_address: Option<&TpAddress>) -> Result<(), AutosarAbstractionError> {
380 if let Some(multicast_address) = multicast_address {
381 self.element()
383 .get_or_create_sub_element(ElementName::MulticastRef)?
384 .set_reference_target(multicast_address.element())?;
385 } else {
386 let _ = self.element().remove_sub_element_kind(ElementName::MulticastRef);
388 }
389 Ok(())
390 }
391
392 #[must_use]
394 pub fn multicast_address(&self) -> Option<TpAddress> {
395 self.element()
396 .get_sub_element(ElementName::MulticastRef)
397 .and_then(|elem| elem.get_reference_target().ok())
398 .and_then(|elem| elem.try_into().ok())
399 }
400}
401
402#[derive(Debug, Clone, PartialEq, Eq, Hash)]
406pub struct FlexrayTpConnectionControl(Element);
407abstraction_element!(FlexrayTpConnectionControl, FlexrayTpConnectionControl);
408impl IdentifiableAbstractionElement for FlexrayTpConnectionControl {}
409
410impl FlexrayTpConnectionControl {
411 pub(crate) fn new(name: &str, parent: &Element) -> Result<Self, AutosarAbstractionError> {
412 let connection_control_elem = parent.create_named_sub_element(ElementName::FlexrayTpConnectionControl, name)?;
413 Ok(Self(connection_control_elem))
414 }
415
416 pub fn set_max_fc_wait(&self, max_fc_wait: u32) -> Result<(), AutosarAbstractionError> {
418 self.element()
419 .get_or_create_sub_element(ElementName::MaxFcWait)?
420 .set_character_data(u64::from(max_fc_wait))?;
421 Ok(())
422 }
423
424 #[must_use]
426 pub fn max_fc_wait(&self) -> Option<u32> {
427 self.element()
428 .get_sub_element(ElementName::MaxFcWait)?
429 .character_data()?
430 .parse_integer()
431 }
432
433 pub fn set_max_number_of_npdu_per_cycle(
435 &self,
436 max_number_of_npdu_per_cycle: u32,
437 ) -> Result<(), AutosarAbstractionError> {
438 self.element()
439 .get_or_create_sub_element(ElementName::MaxNumberOfNpduPerCycle)?
440 .set_character_data(u64::from(max_number_of_npdu_per_cycle))?;
441 Ok(())
442 }
443
444 #[must_use]
446 pub fn max_number_of_npdu_per_cycle(&self) -> Option<u32> {
447 self.element()
448 .get_sub_element(ElementName::MaxNumberOfNpduPerCycle)?
449 .character_data()?
450 .parse_integer()
451 }
452
453 pub fn set_max_retries(&self, max_retries: u32) -> Result<(), AutosarAbstractionError> {
455 self.element()
456 .get_or_create_sub_element(ElementName::MaxRetries)?
457 .set_character_data(u64::from(max_retries))?;
458 Ok(())
459 }
460
461 #[must_use]
463 pub fn max_retries(&self) -> Option<u32> {
464 self.element()
465 .get_sub_element(ElementName::MaxRetries)?
466 .character_data()?
467 .parse_integer()
468 }
469
470 pub fn set_separation_cycle_exponent(&self, separation_cycle_exponent: u32) -> Result<(), AutosarAbstractionError> {
472 self.element()
473 .get_or_create_sub_element(ElementName::SeparationCycleExponent)?
474 .set_character_data(u64::from(separation_cycle_exponent))?;
475 Ok(())
476 }
477
478 #[must_use]
480 pub fn separation_cycle_exponent(&self) -> Option<u32> {
481 self.element()
482 .get_sub_element(ElementName::SeparationCycleExponent)?
483 .character_data()?
484 .parse_integer()
485 }
486}
487
488#[derive(Debug, Clone, PartialEq)]
492pub struct FlexrayTpEcu(Element);
493abstraction_element!(FlexrayTpEcu, FlexrayTpEcu);
494
495impl FlexrayTpEcu {
496 pub(crate) fn new(
497 parent: &Element,
498 ecu_instance: &EcuInstance,
499 full_duplex_enabled: bool,
500 ) -> Result<Self, AutosarAbstractionError> {
501 let tp_ecu_elem = parent.create_sub_element(ElementName::FlexrayTpEcu)?;
502 let tp_ecu = Self(tp_ecu_elem);
503
504 tp_ecu.set_ecu_instance(ecu_instance)?;
505 tp_ecu.set_full_duplex_enabled(full_duplex_enabled)?;
506
507 Ok(tp_ecu)
508 }
509
510 pub fn set_ecu_instance(&self, ecu_instance: &EcuInstance) -> Result<(), AutosarAbstractionError> {
512 self.element()
513 .get_or_create_sub_element(ElementName::EcuInstanceRef)?
514 .set_reference_target(ecu_instance.element())?;
515 Ok(())
516 }
517
518 #[must_use]
520 pub fn ecu_instance(&self) -> Option<EcuInstance> {
521 self.element()
522 .get_sub_element(ElementName::EcuInstanceRef)
523 .and_then(|elem| elem.get_reference_target().ok())
524 .and_then(|elem| EcuInstance::try_from(elem).ok())
525 }
526
527 pub fn set_full_duplex_enabled(&self, full_duplex_enabled: bool) -> Result<(), AutosarAbstractionError> {
529 self.element()
530 .get_or_create_sub_element(ElementName::FullDuplexEnabled)?
531 .set_character_data(full_duplex_enabled)?;
532 Ok(())
533 }
534
535 #[must_use]
537 pub fn full_duplex_enabled(&self) -> Option<bool> {
538 self.element()
539 .get_sub_element(ElementName::FullDuplexEnabled)
540 .and_then(|elem| elem.character_data())
541 .and_then(|cdata| cdata.parse_bool())
542 }
543
544 pub fn set_cycle_time_main_function(
546 &self,
547 cycle_time_main_function: Option<f64>,
548 ) -> Result<(), AutosarAbstractionError> {
549 if let Some(cycle_time_main_function) = cycle_time_main_function {
550 self.element()
551 .get_or_create_sub_element(ElementName::CycleTimeMainFunction)?
552 .set_character_data(cycle_time_main_function)?;
553 } else {
554 let _ = self
555 .element()
556 .remove_sub_element_kind(ElementName::CycleTimeMainFunction);
557 }
558 Ok(())
559 }
560
561 #[must_use]
563 pub fn cycle_time_main_function(&self) -> Option<f64> {
564 self.element()
565 .get_sub_element(ElementName::CycleTimeMainFunction)
566 .and_then(|elem| elem.character_data())
567 .and_then(|cdata| cdata.parse_float())
568 }
569
570 pub fn set_cancellation(&self, cancellation: Option<bool>) -> Result<(), AutosarAbstractionError> {
572 if let Some(cancellation) = cancellation {
573 self.element()
574 .get_or_create_sub_element(ElementName::Cancellation)?
575 .set_character_data(cancellation)?;
576 } else {
577 let _ = self.element().remove_sub_element_kind(ElementName::Cancellation);
578 }
579 Ok(())
580 }
581
582 #[must_use]
584 pub fn cancellation(&self) -> Option<bool> {
585 self.element()
586 .get_sub_element(ElementName::Cancellation)
587 .and_then(|elem| elem.character_data())
588 .and_then(|cdata| cdata.parse_bool())
589 }
590}
591
592#[derive(Debug, Clone, PartialEq, Eq, Hash)]
596pub struct FlexrayTpNode(Element);
597abstraction_element!(FlexrayTpNode, FlexrayTpNode);
598impl IdentifiableAbstractionElement for FlexrayTpNode {}
599
600impl FlexrayTpNode {
601 pub(crate) fn new(name: &str, parent: &Element) -> Result<Self, AutosarAbstractionError> {
602 let node_elem = parent.create_named_sub_element(ElementName::FlexrayTpNode, name)?;
603 Ok(Self(node_elem))
604 }
605
606 pub fn set_tp_address(&self, tp_address: Option<&TpAddress>) -> Result<(), AutosarAbstractionError> {
610 if let Some(tp_address) = tp_address {
611 self.element()
613 .get_or_create_sub_element(ElementName::TpAddressRef)?
614 .set_reference_target(tp_address.element())?;
615 } else {
616 if let Some(tp_address_elem) = self.element().get_sub_element(ElementName::TpAddressRef) {
618 self.element().remove_sub_element(tp_address_elem)?;
619 }
620 }
621 Ok(())
622 }
623
624 #[must_use]
626 pub fn tp_address(&self) -> Option<TpAddress> {
627 self.element()
628 .get_sub_element(ElementName::TpAddressRef)
629 .and_then(|elem| elem.get_reference_target().ok())
630 .and_then(|elem| elem.try_into().ok())
631 }
632
633 pub fn add_communication_connector(
637 &self,
638 connector: &FlexrayCommunicationConnector,
639 ) -> Result<(), AutosarAbstractionError> {
640 let connector_refs = self.element().get_or_create_sub_element(ElementName::ConnectorRefs)?;
641
642 if connector_refs.sub_elements().count() >= 2 {
643 return Err(AutosarAbstractionError::InvalidParameter(
644 "A FlexrayTpNode can only have up to 2 connectors".to_string(),
645 ));
646 }
647 connector_refs
648 .create_sub_element(ElementName::ConnectorRef)?
649 .set_reference_target(connector.element())?;
650 Ok(())
651 }
652
653 pub fn communication_connectors(&self) -> impl Iterator<Item = FlexrayCommunicationConnector> + Send + use<> {
655 self.element()
656 .get_sub_element(ElementName::ConnectorRefs)
657 .into_iter()
658 .flat_map(|elem| elem.sub_elements())
659 .filter_map(|ref_elem| {
660 ref_elem
661 .get_reference_target()
662 .ok()
663 .and_then(|elem| elem.try_into().ok())
664 })
665 }
666}
667
668#[cfg(test)]
671mod test {
672 use super::*;
673 use crate::{
674 AutosarModelAbstraction, SystemCategory,
675 communication::{DiagPduType, FlexrayChannelName, FlexrayClusterSettings},
676 };
677 use autosar_data::AutosarVersion;
678
679 #[test]
680 fn test_flexray_iso_transport_protocol() {
681 let model = AutosarModelAbstraction::create("DoipTp.arxml", AutosarVersion::LATEST);
682 let package = model.get_or_create_package("/pkg1").unwrap();
683
684 let system = package.create_system("system", SystemCategory::EcuExtract).unwrap();
685 let flexray_cluster = system
686 .create_flexray_cluster("flexray_cluster", &package, &FlexrayClusterSettings::default())
687 .unwrap();
688 let flexray_channel = flexray_cluster
689 .create_physical_channel("flexray_channel_a", FlexrayChannelName::A)
690 .unwrap();
691 let ecu_instance = system.create_ecu_instance("ecu_instance", &package).unwrap();
692 let communication_controller = ecu_instance
693 .create_flexray_communication_controller("can_ctrl")
694 .unwrap();
695 let connector = communication_controller
696 .connect_physical_channel("name", &flexray_channel)
697 .unwrap();
698
699 let tp_sdu = system
701 .create_dcm_ipdu("diag", &package, 1024, DiagPduType::DiagRequest)
702 .unwrap();
703 let reversed_tp_sdu = system
705 .create_dcm_ipdu("diag_rev", &package, 1024, DiagPduType::DiagResponse)
706 .unwrap();
707
708 let npdu1 = system.create_n_pdu("npdu1", &package, 64).unwrap();
710 let npdu2 = system.create_n_pdu("npdu2", &package, 64).unwrap();
711
712 let fr_tp_config = system
714 .create_flexray_tp_config("FrTpConfig", &package, &flexray_cluster)
715 .unwrap();
716 assert_eq!(fr_tp_config.cluster().unwrap(), flexray_cluster);
717
718 let fr_tp_pdu_pool_tx = fr_tp_config.create_flexray_tp_pdu_pool("FrTpPduPool_Tx").unwrap();
720 fr_tp_pdu_pool_tx.add_n_pdu(&npdu1).unwrap();
721 assert_eq!(fr_tp_pdu_pool_tx.n_pdus().next(), Some(npdu1));
722 let fr_tp_pdu_pool_rx = fr_tp_config.create_flexray_tp_pdu_pool("FrTpPduPool_Rx").unwrap();
723 fr_tp_pdu_pool_rx.add_n_pdu(&npdu2).unwrap();
724 assert_eq!(fr_tp_pdu_pool_rx.n_pdus().next(), Some(npdu2));
725
726 assert!(fr_tp_config.flexray_tp_pdu_pools().count() == 2);
727
728 let tp_address_1 = fr_tp_config.create_tp_address("TpAddress1", 0x1234).unwrap();
730 assert_eq!(fr_tp_config.tp_addresses().next(), Some(tp_address_1.clone()));
731 assert_eq!(tp_address_1.address().unwrap(), 0x1234);
732 let tp_address_2 = fr_tp_config.create_tp_address("TpAddress2", 0x5678).unwrap();
733 assert_eq!(fr_tp_config.tp_addresses().count(), 2);
734
735 let tp_node_1 = fr_tp_config.create_flexray_tp_node("TpNode1").unwrap();
737 tp_node_1.set_tp_address(Some(&tp_address_1)).unwrap();
738 assert_eq!(tp_node_1.tp_address().unwrap(), tp_address_1);
739 tp_node_1.add_communication_connector(&connector).unwrap();
740 assert_eq!(tp_node_1.communication_connectors().next(), Some(connector));
741 let tp_node_2 = fr_tp_config.create_flexray_tp_node("TpNode2").unwrap();
742 tp_node_2.set_tp_address(Some(&tp_address_2)).unwrap();
743
744 assert_eq!(fr_tp_config.flexray_tp_nodes().count(), 2);
745 assert_eq!(fr_tp_config.flexray_tp_nodes().next(), Some(tp_node_1.clone()));
746
747 let connection_control = fr_tp_config
749 .create_flexray_tp_connection_control("ConnectionControl")
750 .unwrap();
751 assert_eq!(fr_tp_config.flexray_tp_connection_controls().count(), 1);
752 assert_eq!(
753 fr_tp_config.flexray_tp_connection_controls().next().unwrap(),
754 connection_control
755 );
756 connection_control.set_max_fc_wait(10).unwrap();
757 assert_eq!(connection_control.max_fc_wait().unwrap(), 10);
758 connection_control.set_max_number_of_npdu_per_cycle(5).unwrap();
759 assert_eq!(connection_control.max_number_of_npdu_per_cycle().unwrap(), 5);
760 connection_control.set_max_retries(3).unwrap();
761 assert_eq!(connection_control.max_retries().unwrap(), 3);
762 connection_control.set_separation_cycle_exponent(2).unwrap();
763 assert_eq!(connection_control.separation_cycle_exponent().unwrap(), 2);
764
765 let connection = fr_tp_config
767 .create_flexray_tp_connection(None, &tp_node_1, &tp_sdu, &connection_control)
768 .unwrap();
769 assert_eq!(fr_tp_config.flexray_tp_connections().count(), 1);
770 assert_eq!(fr_tp_config.flexray_tp_connections().next().unwrap(), connection);
771
772 connection.add_receiver(&tp_node_2).unwrap();
773 connection.set_tx_pdu_pool(&fr_tp_pdu_pool_tx).unwrap();
774 connection.set_rx_pdu_pool(&fr_tp_pdu_pool_rx).unwrap();
775 connection.set_multicast_address(Some(&tp_address_2)).unwrap();
776 connection.set_reversed_tp_sdu(&reversed_tp_sdu).unwrap();
777 assert_eq!(connection.receivers().count(), 1);
778 assert_eq!(connection.receivers().next(), Some(tp_node_2));
779 assert_eq!(connection.tx_pdu_pool().unwrap(), fr_tp_pdu_pool_tx);
780 assert_eq!(connection.rx_pdu_pool().unwrap(), fr_tp_pdu_pool_rx);
781 assert_eq!(connection.multicast_address().unwrap(), tp_address_2);
782 assert_eq!(connection.connection_control().unwrap(), connection_control);
783 assert_eq!(connection.transmitter().unwrap(), tp_node_1);
784 assert_eq!(connection.direct_tp_sdu().unwrap(), tp_sdu.clone().into());
785 assert_eq!(connection.reversed_tp_sdu().unwrap(), reversed_tp_sdu.clone().into());
786
787 assert_eq!(connection.name(), None);
788 connection.set_name("Connection1").unwrap();
789 assert_eq!(connection.name(), Some("Connection1".to_string()));
790
791 let fr_tp_ecu = fr_tp_config.create_flexray_tp_ecu(&ecu_instance, true).unwrap();
793 fr_tp_ecu.set_cycle_time_main_function(Some(0.01)).unwrap();
794 fr_tp_ecu.set_cancellation(Some(true)).unwrap();
795 assert_eq!(fr_tp_config.flexray_tp_ecus().count(), 1);
796 assert_eq!(fr_tp_config.flexray_tp_ecus().next().unwrap(), fr_tp_ecu);
797 assert_eq!(fr_tp_ecu.ecu_instance().unwrap(), ecu_instance);
798 assert!(fr_tp_ecu.full_duplex_enabled().unwrap());
799 assert_eq!(fr_tp_ecu.cycle_time_main_function().unwrap(), 0.01);
800 assert!(fr_tp_ecu.cancellation().unwrap());
801 }
802}