1use crate::communication::{
2 CanCluster, CanFrame, CanTpConfig, Cluster, ContainerIPdu, ContainerIPduHeaderType, DcmIPdu, DiagPduType,
3 DoIpTpConfig, EthernetCluster, EventGroupControlType, FlexrayArTpConfig, FlexrayCluster, FlexrayClusterSettings,
4 FlexrayFrame, FlexrayTpConfig, Frame, GeneralPurposeIPdu, GeneralPurposeIPduCategory, GeneralPurposePdu,
5 GeneralPurposePduCategory, ISignal, ISignalGroup, ISignalIPdu, LinCluster, MultiplexedIPdu, NPdu, NmConfig, NmPdu,
6 Pdu, RxAcceptContainedIPdu, SecureCommunicationProps, SecuredIPdu, ServiceInstanceCollectionSet, SoAdRoutingGroup,
7 SocketConnectionIpduIdentifierSet, SomeipTpConfig, SystemSignal, SystemSignalGroup,
8};
9use crate::datatype::SwBaseType;
10use crate::software_component::{CompositionSwComponentType, RootSwCompositionPrototype};
11use crate::{
12 AbstractionElement, ArPackage, AutosarAbstractionError, EcuInstance, IdentifiableAbstractionElement,
13 abstraction_element,
14};
15use autosar_data::{AutosarModel, Element, ElementName, WeakElement};
16use std::iter::FusedIterator;
17
18mod mapping;
19
20pub use mapping::*;
21
22#[derive(Debug, Clone, PartialEq, Eq, Hash)]
27pub struct System(Element);
28abstraction_element!(System, System);
29impl IdentifiableAbstractionElement for System {}
30
31impl System {
32 #[must_use]
34 pub(crate) fn find(model: &AutosarModel) -> Option<Self> {
35 let elem = model
36 .identifiable_elements()
37 .filter_map(|(_, weak)| weak.upgrade())
38 .find(|elem| elem.element_name() == ElementName::System)?;
39 Some(Self(elem))
40 }
41
42 pub(crate) fn new(
65 name: &str,
66 package: &ArPackage,
67 category: SystemCategory,
68 ) -> Result<Self, AutosarAbstractionError> {
69 let pkg_elem_elements = package.element().get_or_create_sub_element(ElementName::Elements)?;
70
71 let system_elem = pkg_elem_elements.create_named_sub_element(ElementName::System, name)?;
72 let system = System(system_elem);
73 system.set_category(category)?;
74
75 Ok(system)
76 }
77
78 pub fn set_category(&self, category: SystemCategory) -> Result<(), AutosarAbstractionError> {
80 self.0
81 .get_or_create_sub_element(ElementName::Category)?
82 .set_character_data(category.to_string())?;
83 Ok(())
84 }
85
86 #[must_use]
88 pub fn category(&self) -> Option<SystemCategory> {
89 self.0
90 .get_sub_element(ElementName::Category)?
91 .character_data()?
92 .string_value()?
93 .parse()
94 .ok()
95 }
96
97 pub fn set_pnc_vector_length(&self, length: Option<u32>) -> Result<(), AutosarAbstractionError> {
99 if let Some(length) = length {
100 self.0
101 .get_or_create_sub_element(ElementName::PncVectorLength)?
102 .set_character_data(length as u64)?;
103 } else {
104 let _ = self.0.remove_sub_element_kind(ElementName::PncVectorLength);
105 }
106 Ok(())
107 }
108
109 #[must_use]
111 pub fn pnc_vector_length(&self) -> Option<u32> {
112 self.0
113 .get_sub_element(ElementName::PncVectorLength)?
114 .character_data()?
115 .parse_integer()
116 }
117
118 pub fn set_pnc_vector_offset(&self, offset: Option<u32>) -> Result<(), AutosarAbstractionError> {
120 if let Some(offset) = offset {
121 self.0
122 .get_or_create_sub_element(ElementName::PncVectorOffset)?
123 .set_character_data(offset as u64)?;
124 } else {
125 let _ = self.0.remove_sub_element_kind(ElementName::PncVectorOffset);
126 }
127 Ok(())
128 }
129
130 #[must_use]
132 pub fn pnc_vector_offset(&self) -> Option<u32> {
133 self.0
134 .get_sub_element(ElementName::PncVectorOffset)?
135 .character_data()?
136 .parse_integer()
137 }
138
139 pub fn create_ecu_instance(&self, name: &str, package: &ArPackage) -> Result<EcuInstance, AutosarAbstractionError> {
159 let ecu_instance = EcuInstance::new(name, package)?;
160 self.create_fibex_element_ref_unchecked(ecu_instance.element())?;
161
162 Ok(ecu_instance)
163 }
164
165 pub fn ecu_instances(&self) -> impl Iterator<Item = EcuInstance> + Send + use<> {
185 EcuInstanceIterator::new(self)
186 }
187
188 pub fn create_can_cluster(
212 &self,
213 cluster_name: &str,
214 package: &ArPackage,
215 can_baudrate: Option<u32>,
216 ) -> Result<CanCluster, AutosarAbstractionError> {
217 let cluster = CanCluster::new(cluster_name, package, can_baudrate)?;
218 self.create_fibex_element_ref_unchecked(cluster.element())?;
219
220 Ok(cluster)
221 }
222
223 pub fn create_ethernet_cluster(
248 &self,
249 cluster_name: &str,
250 package: &ArPackage,
251 ) -> Result<EthernetCluster, AutosarAbstractionError> {
252 let cluster = EthernetCluster::new(cluster_name, package)?;
253 self.create_fibex_element_ref_unchecked(cluster.element())?;
254
255 Ok(cluster)
256 }
257
258 pub fn create_flexray_cluster(
284 &self,
285 cluster_name: &str,
286 package: &ArPackage,
287 settings: &FlexrayClusterSettings,
288 ) -> Result<FlexrayCluster, AutosarAbstractionError> {
289 let cluster = FlexrayCluster::new(cluster_name, package, settings)?;
290 self.create_fibex_element_ref_unchecked(cluster.element())?;
291
292 Ok(cluster)
293 }
294
295 pub fn create_lin_cluster(
319 &self,
320 cluster_name: &str,
321 package: &ArPackage,
322 ) -> Result<LinCluster, AutosarAbstractionError> {
323 let cluster = LinCluster::new(cluster_name, package)?;
324 self.create_fibex_element_ref_unchecked(cluster.element())?;
325
326 Ok(cluster)
327 }
328
329 pub fn clusters(&self) -> impl Iterator<Item = Cluster> + Send + use<> {
350 self.0
351 .get_sub_element(ElementName::FibexElements)
352 .into_iter()
353 .flat_map(|fibexelems| fibexelems.sub_elements())
354 .filter_map(|ferc| {
355 ferc.get_sub_element(ElementName::FibexElementRef)
356 .and_then(|fer| fer.get_reference_target().ok())
357 .and_then(|elem| Cluster::try_from(elem).ok())
358 })
359 }
360
361 pub fn create_can_frame(
365 &self,
366 name: &str,
367 package: &ArPackage,
368 byte_length: u64,
369 ) -> Result<CanFrame, AutosarAbstractionError> {
370 let can_frame = CanFrame::new(name, package, byte_length)?;
371 self.create_fibex_element_ref_unchecked(can_frame.element())?;
372
373 Ok(can_frame)
374 }
375
376 pub fn create_flexray_frame(
380 &self,
381 name: &str,
382 package: &ArPackage,
383 byte_length: u64,
384 ) -> Result<FlexrayFrame, AutosarAbstractionError> {
385 let flexray_frame = FlexrayFrame::new(name, package, byte_length)?;
386 self.create_fibex_element_ref_unchecked(flexray_frame.element())?;
387
388 Ok(flexray_frame)
389 }
390
391 pub fn frames(&self) -> impl Iterator<Item = Frame> + Send + use<> {
395 self.0
396 .get_sub_element(ElementName::FibexElements)
397 .into_iter()
398 .flat_map(|fibexelems| fibexelems.sub_elements())
399 .filter_map(|ferc| {
400 ferc.get_sub_element(ElementName::FibexElementRef)
401 .and_then(|fer| fer.get_reference_target().ok())
402 .and_then(|elem| Frame::try_from(elem).ok())
403 })
404 }
405
406 pub fn create_isignal(
430 &self,
431 name: &str,
432 package: &ArPackage,
433 bit_length: u64,
434 syssignal: &SystemSignal,
435 datatype: Option<&SwBaseType>,
436 ) -> Result<ISignal, AutosarAbstractionError> {
437 let i_signal = ISignal::new(name, package, bit_length, syssignal, datatype)?;
438
439 self.create_fibex_element_ref_unchecked(i_signal.element())?;
440
441 Ok(i_signal)
442 }
443
444 pub fn isignals(&self) -> impl Iterator<Item = ISignal> + Send + use<> {
448 self.0
449 .get_sub_element(ElementName::FibexElements)
450 .into_iter()
451 .flat_map(|fibexelems| fibexelems.sub_elements())
452 .filter_map(|ferc| {
453 ferc.get_sub_element(ElementName::FibexElementRef)
454 .and_then(|fer| fer.get_reference_target().ok())
455 .and_then(|elem| ISignal::try_from(elem).ok())
456 })
457 }
458
459 pub fn create_isignal_group(
486 &self,
487 name: &str,
488 package: &ArPackage,
489 system_signal_group: &SystemSignalGroup,
490 ) -> Result<ISignalGroup, AutosarAbstractionError> {
491 let i_signal_group = ISignalGroup::new(name, package, system_signal_group)?;
492
493 self.create_fibex_element_ref_unchecked(i_signal_group.element())?;
494
495 Ok(i_signal_group)
496 }
497
498 pub fn isignal_groups(&self) -> impl Iterator<Item = ISignalGroup> + Send + use<> {
502 self.0
503 .get_sub_element(ElementName::FibexElements)
504 .into_iter()
505 .flat_map(|fibexelems| fibexelems.sub_elements())
506 .filter_map(|ferc| {
507 ferc.get_sub_element(ElementName::FibexElementRef)
508 .and_then(|fer| fer.get_reference_target().ok())
509 .and_then(|elem| ISignalGroup::try_from(elem).ok())
510 })
511 }
512
513 pub fn create_isignal_ipdu(
534 &self,
535 name: &str,
536 package: &ArPackage,
537 length: u32,
538 ) -> Result<ISignalIPdu, AutosarAbstractionError> {
539 let pdu = ISignalIPdu::new(name, package, length)?;
540 self.create_fibex_element_ref_unchecked(pdu.element())?;
541
542 Ok(pdu)
543 }
544
545 pub fn create_nm_pdu(
566 &self,
567 name: &str,
568 package: &ArPackage,
569 length: u32,
570 ) -> Result<NmPdu, AutosarAbstractionError> {
571 let pdu = NmPdu::new(name, package, length)?;
572 self.create_fibex_element_ref_unchecked(pdu.element())?;
573
574 Ok(pdu)
575 }
576
577 pub fn create_n_pdu(&self, name: &str, package: &ArPackage, length: u32) -> Result<NPdu, AutosarAbstractionError> {
598 let pdu = NPdu::new(name, package, length)?;
599 self.create_fibex_element_ref_unchecked(pdu.element())?;
600
601 Ok(pdu)
602 }
603
604 pub fn create_dcm_ipdu(
625 &self,
626 name: &str,
627 package: &ArPackage,
628 length: u32,
629 diag_pdu_type: DiagPduType,
630 ) -> Result<DcmIPdu, AutosarAbstractionError> {
631 let pdu = DcmIPdu::new(name, package, length, diag_pdu_type)?;
632 self.create_fibex_element_ref_unchecked(pdu.element())?;
633
634 Ok(pdu)
635 }
636
637 pub fn create_general_purpose_pdu(
658 &self,
659 name: &str,
660 package: &ArPackage,
661 length: u32,
662 category: GeneralPurposePduCategory,
663 ) -> Result<GeneralPurposePdu, AutosarAbstractionError> {
664 let pdu = GeneralPurposePdu::new(name, package, length, category)?;
665 self.create_fibex_element_ref_unchecked(pdu.element())?;
666
667 Ok(pdu)
668 }
669
670 pub fn create_general_purpose_ipdu(
691 &self,
692 name: &str,
693 package: &ArPackage,
694 length: u32,
695 category: GeneralPurposeIPduCategory,
696 ) -> Result<GeneralPurposeIPdu, AutosarAbstractionError> {
697 let pdu = GeneralPurposeIPdu::new(name, package, length, category)?;
698 self.create_fibex_element_ref_unchecked(pdu.element())?;
699
700 Ok(pdu)
701 }
702
703 pub fn create_container_ipdu(
724 &self,
725 name: &str,
726 package: &ArPackage,
727 length: u32,
728 header_type: ContainerIPduHeaderType,
729 rx_accept: RxAcceptContainedIPdu,
730 ) -> Result<ContainerIPdu, AutosarAbstractionError> {
731 let pdu = ContainerIPdu::new(name, package, length, header_type, rx_accept)?;
732 self.create_fibex_element_ref_unchecked(pdu.element())?;
733
734 Ok(pdu)
735 }
736
737 pub fn create_secured_ipdu(
759 &self,
760 name: &str,
761 package: &ArPackage,
762 length: u32,
763 secure_props: &SecureCommunicationProps,
764 ) -> Result<SecuredIPdu, AutosarAbstractionError> {
765 let pdu = SecuredIPdu::new(name, package, length, secure_props)?;
766 self.create_fibex_element_ref_unchecked(pdu.element())?;
767
768 Ok(pdu)
769 }
770
771 pub fn create_multiplexed_ipdu(
792 &self,
793 name: &str,
794 package: &ArPackage,
795 length: u32,
796 ) -> Result<MultiplexedIPdu, AutosarAbstractionError> {
797 let pdu = MultiplexedIPdu::new(name, package, length)?;
798 self.create_fibex_element_ref_unchecked(pdu.element())?;
799
800 Ok(pdu)
801 }
802
803 pub fn pdus(&self) -> impl Iterator<Item = Pdu> + Send + use<> {
807 self.0
808 .get_sub_element(ElementName::FibexElements)
809 .into_iter()
810 .flat_map(|fibexelems| fibexelems.sub_elements())
811 .filter_map(|ferc| {
812 ferc.get_sub_element(ElementName::FibexElementRef)
813 .and_then(|fer| fer.get_reference_target().ok())
814 .and_then(|elem| Pdu::try_from(elem).ok())
815 })
816 }
817
818 pub fn create_socket_connection_ipdu_identifier_set(
836 &self,
837 name: &str,
838 package: &ArPackage,
839 ) -> Result<SocketConnectionIpduIdentifierSet, AutosarAbstractionError> {
840 let set = SocketConnectionIpduIdentifierSet::new(name, package)?;
841 self.create_fibex_element_ref_unchecked(set.element())?;
842
843 Ok(set)
844 }
845
846 pub fn create_so_ad_routing_group(
852 &self,
853 name: &str,
854 package: &ArPackage,
855 control_type: Option<EventGroupControlType>,
856 ) -> Result<SoAdRoutingGroup, AutosarAbstractionError> {
857 let group = SoAdRoutingGroup::new(name, package, control_type)?;
858 self.create_fibex_element_ref_unchecked(group.element())?;
859
860 Ok(group)
861 }
862
863 pub fn create_service_instance_collection_set(
867 &self,
868 name: &str,
869 package: &ArPackage,
870 ) -> Result<ServiceInstanceCollectionSet, AutosarAbstractionError> {
871 let set = ServiceInstanceCollectionSet::new(name, package)?;
872 self.create_fibex_element_ref_unchecked(set.element())?;
873
874 Ok(set)
875 }
876
877 pub fn create_someip_tp_config<T: Into<Cluster> + Clone>(
881 &self,
882 name: &str,
883 package: &ArPackage,
884 cluster: &T,
885 ) -> Result<SomeipTpConfig, AutosarAbstractionError> {
886 let config = SomeipTpConfig::new(name, package, &cluster.clone().into())?;
887 self.create_fibex_element_ref_unchecked(config.element())?;
888
889 Ok(config)
890 }
891
892 pub fn create_can_tp_config(
896 &self,
897 name: &str,
898 package: &ArPackage,
899 can_cluster: &CanCluster,
900 ) -> Result<CanTpConfig, AutosarAbstractionError> {
901 let config = CanTpConfig::new(name, package, can_cluster)?;
902 self.create_fibex_element_ref_unchecked(config.element())?;
903
904 Ok(config)
905 }
906
907 pub fn create_doip_tp_config(
911 &self,
912 name: &str,
913 package: &ArPackage,
914 eth_cluster: &EthernetCluster,
915 ) -> Result<DoIpTpConfig, AutosarAbstractionError> {
916 let config = DoIpTpConfig::new(name, package, eth_cluster)?;
917 self.create_fibex_element_ref_unchecked(config.element())?;
918
919 Ok(config)
920 }
921
922 pub fn create_flexray_tp_config(
927 &self,
928 name: &str,
929 package: &ArPackage,
930 flexray_cluster: &FlexrayCluster,
931 ) -> Result<FlexrayTpConfig, AutosarAbstractionError> {
932 let config = FlexrayTpConfig::new(name, package, flexray_cluster)?;
933 self.create_fibex_element_ref_unchecked(config.element())?;
934
935 Ok(config)
936 }
937
938 pub fn create_flexray_ar_tp_config(
943 &self,
944 name: &str,
945 package: &ArPackage,
946 flexray_cluster: &FlexrayCluster,
947 ) -> Result<FlexrayArTpConfig, AutosarAbstractionError> {
948 let config = FlexrayArTpConfig::new(name, package, flexray_cluster)?;
949 self.create_fibex_element_ref_unchecked(config.element())?;
950
951 Ok(config)
952 }
953
954 pub fn create_nm_config(&self, name: &str, package: &ArPackage) -> Result<NmConfig, AutosarAbstractionError> {
959 let config = NmConfig::new(name, package)?;
960 self.create_fibex_element_ref_unchecked(config.element())?;
961
962 Ok(config)
963 }
964
965 #[must_use]
969 pub fn nm_config(&self) -> Option<NmConfig> {
970 self.0
971 .get_sub_element(ElementName::FibexElements)
972 .into_iter()
973 .flat_map(|fibexelems| fibexelems.sub_elements())
974 .find_map(|ferc| {
975 ferc.get_sub_element(ElementName::FibexElementRef)
976 .and_then(|fer| fer.get_reference_target().ok())
977 .and_then(|elem| NmConfig::try_from(elem).ok())
978 })
979 }
980
981 pub fn create_fibex_element_ref(&self, elem: &Element) -> Result<(), AutosarAbstractionError> {
1005 let model = elem.model()?;
1006 let refs = model.get_references_to(&elem.path()?);
1007 for reference in refs.iter().filter_map(WeakElement::upgrade) {
1008 if reference.element_name() == ElementName::FibexElementRef {
1009 return Ok(());
1011 }
1012 }
1013 self.create_fibex_element_ref_unchecked(elem)
1014 }
1015
1016 fn create_fibex_element_ref_unchecked(&self, elem: &Element) -> Result<(), AutosarAbstractionError> {
1017 let fibex_elements = self.0.get_or_create_sub_element(ElementName::FibexElements)?;
1018 let fibex_element_ref = fibex_elements
1019 .create_sub_element(ElementName::FibexElementRefConditional)?
1020 .create_sub_element(ElementName::FibexElementRef)?;
1021 fibex_element_ref.set_reference_target(elem)?;
1022 Ok(())
1023 }
1024
1025 pub fn set_root_sw_composition(
1030 &self,
1031 name: &str,
1032 composition_type: &CompositionSwComponentType,
1033 ) -> Result<RootSwCompositionPrototype, AutosarAbstractionError> {
1034 let root_compositions = self
1035 .0
1036 .get_or_create_sub_element(ElementName::RootSoftwareCompositions)?;
1037
1038 if let Some(existing_composition) = root_compositions.get_sub_element(ElementName::RootSwCompositionPrototype) {
1039 root_compositions.remove_sub_element(existing_composition)?;
1040 }
1041 RootSwCompositionPrototype::new(name, &root_compositions, composition_type)
1042 }
1043
1044 #[must_use]
1046 pub fn root_sw_composition(&self) -> Option<RootSwCompositionPrototype> {
1047 let root_compositions = self.element().get_sub_element(ElementName::RootSoftwareCompositions)?;
1048 let root_composition = root_compositions.get_sub_element(ElementName::RootSwCompositionPrototype)?;
1049 RootSwCompositionPrototype::try_from(root_composition).ok()
1050 }
1051
1052 pub fn get_or_create_mapping(&self, name: &str) -> Result<SystemMapping, AutosarAbstractionError> {
1057 if let Some(mapping) = self.0.get_sub_element(ElementName::Mappings) {
1058 if let Some(mapping) = mapping.get_sub_element(ElementName::SystemMapping) {
1059 return SystemMapping::try_from(mapping);
1060 }
1061 }
1062 SystemMapping::new(name, self)
1063 }
1064}
1065
1066#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1070pub enum SystemCategory {
1071 SystemConstraints,
1073 SystemDescription,
1075 SystemExtract,
1077 EcuExtract,
1079 AbstractSystemDescription,
1081 EcuSystemDescription,
1083 SwClusterSystemDescription,
1085 RptSystem,
1087}
1088
1089impl std::fmt::Display for SystemCategory {
1090 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1091 match self {
1092 SystemCategory::SystemConstraints => f.write_str("SYSTEM_CONSTRAINTS"),
1093 SystemCategory::SystemDescription => f.write_str("SYSTEM_DESCRIPTION"),
1094 SystemCategory::SystemExtract => f.write_str("SYSTEM_EXTRACT"),
1095 SystemCategory::EcuExtract => f.write_str("ECU_EXTRACT"),
1096 SystemCategory::AbstractSystemDescription => f.write_str("ABSTRACT_SYSTEM_DESCRIPTION"),
1097 SystemCategory::EcuSystemDescription => f.write_str("ECU_SYSTEM_DESCRIPTION"),
1098 SystemCategory::SwClusterSystemDescription => f.write_str("SW_CLUSTER_SYSTEM_DESCRIPTION"),
1099 SystemCategory::RptSystem => f.write_str("RPT_SYSTEM"),
1100 }
1101 }
1102}
1103
1104impl std::str::FromStr for SystemCategory {
1105 type Err = AutosarAbstractionError;
1106
1107 fn from_str(s: &str) -> Result<Self, Self::Err> {
1108 match s {
1109 "SYSTEM_CONSTRAINTS" => Ok(SystemCategory::SystemConstraints),
1110 "SYSTEM_DESCRIPTION" => Ok(SystemCategory::SystemDescription),
1111 "SYSTEM_EXTRACT" => Ok(SystemCategory::SystemExtract),
1112 "ECU_EXTRACT" => Ok(SystemCategory::EcuExtract),
1113 "ABSTRACT_SYSTEM_DESCRIPTION" => Ok(SystemCategory::AbstractSystemDescription),
1114 "ECU_SYSTEM_DESCRIPTION" => Ok(SystemCategory::EcuSystemDescription),
1115 "SW_CLUSTER_SYSTEM_DESCRIPTION" => Ok(SystemCategory::SwClusterSystemDescription),
1116 "RPT_SYSTEM" => Ok(SystemCategory::RptSystem),
1117 _ => Err(AutosarAbstractionError::InvalidParameter(s.to_string())),
1118 }
1119 }
1120}
1121
1122pub struct EcuInstanceIterator {
1126 fibex_elements: Option<Element>,
1127 position: usize,
1128}
1129
1130impl EcuInstanceIterator {
1131 pub(crate) fn new(system: &System) -> Self {
1132 let fibex_elements = system.0.get_sub_element(ElementName::FibexElements);
1133
1134 EcuInstanceIterator {
1135 fibex_elements,
1136 position: 0,
1137 }
1138 }
1139}
1140
1141impl Iterator for EcuInstanceIterator {
1142 type Item = EcuInstance;
1143
1144 fn next(&mut self) -> Option<Self::Item> {
1145 let fibelem = self.fibex_elements.as_ref()?;
1146
1147 while let Some(fibrefcond) = fibelem.get_sub_element_at(self.position) {
1148 self.position += 1;
1149 if let Some(ecuinstance) = fibrefcond
1150 .get_sub_element(ElementName::FibexElementRef)
1151 .and_then(|r| r.get_reference_target().ok())
1152 .and_then(|target| EcuInstance::try_from(target).ok())
1153 {
1154 return Some(ecuinstance);
1155 }
1156 }
1157 self.fibex_elements = None;
1158 None
1159 }
1160}
1161
1162impl FusedIterator for EcuInstanceIterator {}
1163
1164#[cfg(test)]
1167mod test {
1168 use crate::{
1169 AbstractionElement, AutosarModelAbstraction, IdentifiableAbstractionElement, System,
1170 communication::{
1171 ContainerIPduHeaderType, DiagPduType, FlexrayClusterSettings, GeneralPurposeIPduCategory,
1172 GeneralPurposePduCategory, RxAcceptContainedIPdu, SecureCommunicationProps,
1173 },
1174 software_component::CompositionSwComponentType,
1175 system::SystemCategory,
1176 };
1177 use autosar_data::{AutosarVersion, ElementName};
1178
1179 #[test]
1180 fn system() {
1181 let model = AutosarModelAbstraction::create("filename", AutosarVersion::LATEST);
1182
1183 let result = model.find_system();
1185 assert!(result.is_none());
1186
1187 let package = model.get_or_create_package("/SYSTEM").unwrap();
1189 let system = package.create_system("System", SystemCategory::SystemExtract).unwrap();
1190
1191 let system_2 = model.find_system().unwrap();
1193 assert_eq!(system, system_2);
1194
1195 assert_eq!(system.name().unwrap(), "System");
1197 system.set_name("NewName").unwrap();
1198 assert_eq!(system.name().unwrap(), "NewName");
1199
1200 assert_eq!(system.category().unwrap(), SystemCategory::SystemExtract);
1202 system.set_category(SystemCategory::EcuExtract).unwrap();
1203 assert_eq!(system.category().unwrap(), SystemCategory::EcuExtract);
1204
1205 assert!(system.pnc_vector_length().is_none());
1207 system.set_pnc_vector_length(Some(42)).unwrap();
1208 assert_eq!(system.pnc_vector_length().unwrap(), 42);
1209 system.set_pnc_vector_length(None).unwrap();
1210 assert!(system.pnc_vector_length().is_none());
1211
1212 assert!(system.pnc_vector_offset().is_none());
1214 system.set_pnc_vector_offset(Some(42)).unwrap();
1215 assert_eq!(system.pnc_vector_offset().unwrap(), 42);
1216 system.set_pnc_vector_offset(None).unwrap();
1217 assert!(system.pnc_vector_offset().is_none());
1218 }
1219
1220 #[test]
1221 fn system_category() {
1222 let model = AutosarModelAbstraction::create("filename", AutosarVersion::LATEST);
1223 let package = model.get_or_create_package("/SYSTEM").unwrap();
1224 System::new("System", &package, SystemCategory::AbstractSystemDescription).unwrap();
1225
1226 let model = AutosarModelAbstraction::create("filename", AutosarVersion::LATEST);
1227 let package = model.get_or_create_package("/SYSTEM").unwrap();
1228 System::new("System", &package, SystemCategory::EcuExtract).unwrap();
1229
1230 let model = AutosarModelAbstraction::create("filename", AutosarVersion::LATEST);
1231 let package = model.get_or_create_package("/SYSTEM").unwrap();
1232 System::new("System", &package, SystemCategory::EcuSystemDescription).unwrap();
1233
1234 let model = AutosarModelAbstraction::create("filename", AutosarVersion::LATEST);
1235 let package = model.get_or_create_package("/SYSTEM").unwrap();
1236 System::new("System", &package, SystemCategory::RptSystem).unwrap();
1237
1238 let model = AutosarModelAbstraction::create("filename", AutosarVersion::LATEST);
1239 let package = model.get_or_create_package("/SYSTEM").unwrap();
1240 System::new("System", &package, SystemCategory::SwClusterSystemDescription).unwrap();
1241
1242 let model = AutosarModelAbstraction::create("filename", AutosarVersion::LATEST);
1243 let package = model.get_or_create_package("/SYSTEM").unwrap();
1244 System::new("System", &package, SystemCategory::SystemConstraints).unwrap();
1245
1246 let model = AutosarModelAbstraction::create("filename", AutosarVersion::LATEST);
1247 let package = model.get_or_create_package("/SYSTEM").unwrap();
1248 System::new("System", &package, SystemCategory::SystemDescription).unwrap();
1249
1250 let model = AutosarModelAbstraction::create("filename", AutosarVersion::LATEST);
1251 let package = model.get_or_create_package("/SYSTEM").unwrap();
1252 System::new("System", &package, SystemCategory::SystemExtract).unwrap();
1253 }
1254
1255 #[test]
1256 fn fibex_ref() {
1257 let model = AutosarModelAbstraction::create("filename", AutosarVersion::LATEST);
1258 let package = model.get_or_create_package("/SYSTEM").unwrap();
1259 let system = package
1260 .create_system("System", SystemCategory::SystemDescription)
1261 .unwrap();
1262
1263 let el_elements = package
1264 .element()
1265 .get_or_create_sub_element(ElementName::Elements)
1266 .unwrap();
1267 let el_ecuinst = el_elements
1268 .create_named_sub_element(ElementName::EcuInstance, "Ecu")
1269 .unwrap();
1270
1271 let el_fibex_elements = system
1272 .element()
1273 .get_or_create_sub_element(ElementName::FibexElements)
1274 .unwrap();
1275 assert_eq!(el_fibex_elements.sub_elements().count(), 0);
1276
1277 system.create_fibex_element_ref(&el_ecuinst).unwrap();
1279 assert_eq!(el_fibex_elements.sub_elements().count(), 1);
1280 system.create_fibex_element_ref(&el_ecuinst).unwrap();
1282 assert_eq!(el_fibex_elements.sub_elements().count(), 1);
1283 }
1284
1285 #[test]
1286 fn ecu_instance_iterator() {
1287 let model = AutosarModelAbstraction::create("filename", AutosarVersion::LATEST);
1288 let package_1 = model.get_or_create_package("/SYSTEM").unwrap();
1289 let system = package_1
1290 .create_system("System", SystemCategory::SystemExtract)
1291 .unwrap();
1292 let package_2 = model.get_or_create_package("/ECU").unwrap();
1293 system.create_ecu_instance("Ecu_1", &package_2).unwrap();
1294 system.create_ecu_instance("Ecu_2", &package_2).unwrap();
1295 system.create_ecu_instance("Ecu_3", &package_2).unwrap();
1296
1297 let mut iter = system.ecu_instances();
1298 let item = iter.next().unwrap();
1299 assert_eq!(item.name().unwrap(), "Ecu_1");
1300 assert_eq!(model.get_element_by_path("/ECU/Ecu_1").unwrap(), *item.element());
1301 let item = iter.next().unwrap();
1302 assert_eq!(item.name().unwrap(), "Ecu_2");
1303 assert_eq!(model.get_element_by_path("/ECU/Ecu_2").unwrap(), *item.element());
1304 let item = iter.next().unwrap();
1305 assert_eq!(item.name().unwrap(), "Ecu_3");
1306 assert_eq!(model.get_element_by_path("/ECU/Ecu_3").unwrap(), *item.element());
1307
1308 assert!(iter.next().is_none());
1309 assert!(iter.next().is_none());
1311 }
1312
1313 #[test]
1314 fn cluster_iterator() {
1315 let model = AutosarModelAbstraction::create("filename", AutosarVersion::LATEST);
1316 let package_1 = model.get_or_create_package("/SYSTEM").unwrap();
1317 let system = package_1
1318 .create_system("System", SystemCategory::SystemExtract)
1319 .unwrap();
1320 let package_2 = model.get_or_create_package("/Clusters").unwrap();
1321
1322 system.create_can_cluster("CanCluster", &package_2, None).unwrap();
1323
1324 let settings = FlexrayClusterSettings::new();
1325 system
1326 .create_flexray_cluster("FlexrayCluster", &package_2, &settings)
1327 .unwrap();
1328
1329 system.create_ethernet_cluster("EthernetCluster", &package_2).unwrap();
1330 system.create_lin_cluster("LinCluster", &package_2).unwrap();
1331
1332 let package_3 = model.get_or_create_package("/ECU").unwrap();
1334 system.create_ecu_instance("Ecu_1", &package_3).unwrap();
1335
1336 assert_eq!(system.clusters().count(), 4);
1337 }
1338
1339 #[test]
1340 fn frames_iterator() {
1341 let model = AutosarModelAbstraction::create("filename", AutosarVersion::LATEST);
1342 let package_1 = model.get_or_create_package("/SYSTEM").unwrap();
1343 let system = package_1
1344 .create_system("System", SystemCategory::SystemExtract)
1345 .unwrap();
1346 let package_2 = model.get_or_create_package("/Frames").unwrap();
1347
1348 system.create_can_frame("CanFrame", &package_2, 8).unwrap();
1349 system.create_flexray_frame("FlexrayFrame", &package_2, 8).unwrap();
1350
1351 let package_3 = model.get_or_create_package("/ECU").unwrap();
1353 system.create_ecu_instance("Ecu_1", &package_3).unwrap();
1354
1355 assert_eq!(system.frames().count(), 2);
1356 }
1357
1358 #[test]
1359 fn signals_iterator() {
1360 let model = AutosarModelAbstraction::create("filename", AutosarVersion::LATEST);
1361 let package_1 = model.get_or_create_package("/SYSTEM").unwrap();
1362 let system = package_1
1363 .create_system("System", SystemCategory::SystemExtract)
1364 .unwrap();
1365 let package_2 = model.get_or_create_package("/Signals").unwrap();
1366
1367 let syssig1 = package_2.create_system_signal("syssig1").unwrap();
1368 system.create_isignal("Sig1", &package_2, 8, &syssig1, None).unwrap();
1369 let syssig2 = package_2.create_system_signal("syssig2").unwrap();
1370 system.create_isignal("Sig2", &package_2, 8, &syssig2, None).unwrap();
1371
1372 let package_3 = model.get_or_create_package("/ECU").unwrap();
1374 system.create_ecu_instance("Ecu_1", &package_3).unwrap();
1375
1376 assert_eq!(system.isignals().count(), 2);
1377 }
1378
1379 #[test]
1380 fn isignal_groups_iterator() {
1381 let model = AutosarModelAbstraction::create("filename", AutosarVersion::LATEST);
1382 let package_1 = model.get_or_create_package("/SYSTEM").unwrap();
1383 let system = package_1
1384 .create_system("System", SystemCategory::SystemExtract)
1385 .unwrap();
1386 let package_2 = model.get_or_create_package("/SignalGroups").unwrap();
1387
1388 let sysgroup1 = package_2.create_system_signal_group("sysgroup1").unwrap();
1389 system
1390 .create_isignal_group("siggroup1", &package_2, &sysgroup1)
1391 .unwrap();
1392 let sysgroup2 = package_2.create_system_signal_group("sysgroup2").unwrap();
1393 system
1394 .create_isignal_group("siggroup2", &package_2, &sysgroup2)
1395 .unwrap();
1396
1397 let package_3 = model.get_or_create_package("/ECU").unwrap();
1399 system.create_ecu_instance("Ecu_1", &package_3).unwrap();
1400
1401 assert_eq!(system.isignal_groups().count(), 2);
1402 }
1403
1404 #[test]
1405 fn pdus_iterator() {
1406 let model = AutosarModelAbstraction::create("filename", AutosarVersion::LATEST);
1407 let package_1 = model.get_or_create_package("/SYSTEM").unwrap();
1408 let system = package_1
1409 .create_system("System", SystemCategory::SystemExtract)
1410 .unwrap();
1411 let package_2 = model.get_or_create_package("/Pdus").unwrap();
1412
1413 system
1414 .create_dcm_ipdu("DcmIpdu", &package_2, 8, DiagPduType::DiagRequest)
1415 .unwrap();
1416 system
1417 .create_general_purpose_pdu("GeneralPurposePdu", &package_2, 8, GeneralPurposePduCategory::DoIp)
1418 .unwrap();
1419 system
1420 .create_general_purpose_ipdu("GeneralPurposeIpdu", &package_2, 8, GeneralPurposeIPduCategory::Xcp)
1421 .unwrap();
1422 system
1423 .create_container_ipdu(
1424 "ContainerIpdu",
1425 &package_2,
1426 8,
1427 ContainerIPduHeaderType::NoHeader,
1428 RxAcceptContainedIPdu::AcceptAll,
1429 )
1430 .unwrap();
1431 system
1432 .create_secured_ipdu("SecuredIpdu", &package_2, 8, &SecureCommunicationProps::default())
1433 .unwrap();
1434 system
1435 .create_multiplexed_ipdu("MultiplexedIpdu", &package_2, 8)
1436 .unwrap();
1437
1438 let package_3 = model.get_or_create_package("/ECU").unwrap();
1440 system.create_ecu_instance("Ecu_1", &package_3).unwrap();
1441
1442 assert_eq!(system.pdus().count(), 6);
1443 }
1444
1445 #[test]
1446 fn nm_config() {
1447 let model = AutosarModelAbstraction::create("filename", AutosarVersion::LATEST);
1448 let sys_package = model.get_or_create_package("/SYSTEM").unwrap();
1449 let system = sys_package
1450 .create_system("System", SystemCategory::SystemExtract)
1451 .unwrap();
1452
1453 assert!(system.nm_config().is_none());
1454
1455 let nm_package = model.get_or_create_package("/Nm").unwrap();
1456 let nm_config = system.create_nm_config("NmConfig", &nm_package).unwrap();
1457
1458 assert!(system.nm_config().is_some());
1459 assert_eq!(system.nm_config().unwrap(), nm_config);
1460 }
1461
1462 #[test]
1463 fn sw_mapping() {
1464 let model = AutosarModelAbstraction::create("filename", AutosarVersion::LATEST);
1465 let package_1 = model.get_or_create_package("/SYSTEM").unwrap();
1466 let system = package_1
1467 .create_system("System", SystemCategory::SystemExtract)
1468 .unwrap();
1469 let package_2 = model.get_or_create_package("/SWC").unwrap();
1470 let package_3 = model.get_or_create_package("/ECU").unwrap();
1471
1472 let root_composition = CompositionSwComponentType::new("RootComposition", &package_2).unwrap();
1473 let context_composition = CompositionSwComponentType::new("ContextComposition", &package_2).unwrap();
1474 let ecu_composition = CompositionSwComponentType::new("EcuComposition", &package_2).unwrap();
1475 let _root_proto = system
1476 .set_root_sw_composition("RootComposition", &root_composition)
1477 .unwrap();
1478 assert_eq!(system.root_sw_composition().unwrap(), _root_proto);
1479
1480 let context_proto = root_composition
1481 .create_component("ContextComposition", &context_composition.clone())
1482 .unwrap();
1483 let ecu_proto = context_composition
1484 .create_component("EcuComposition", &ecu_composition)
1485 .unwrap();
1486 let ecu = system.create_ecu_instance("Ecu", &package_3).unwrap();
1487
1488 let mapping = system.get_or_create_mapping("Mapping").unwrap();
1489 mapping.map_swc_to_ecu("SwcToEcu1", &context_proto, &ecu).unwrap();
1490 let swc_to_ecu = mapping.map_swc_to_ecu("SwcToEcu2", &ecu_proto, &ecu).unwrap();
1491
1492 assert_eq!(swc_to_ecu.target_component().unwrap(), ecu_proto);
1493 assert_eq!(swc_to_ecu.ecu_instance().unwrap(), ecu);
1494
1495 }
1497}