1use crate::communication::{AbstractIpdu, AbstractPdu, IPdu, ISignal, ISignalGroup, Pdu, TransferProperty};
2use crate::{
3 AbstractionElement, ArPackage, AutosarAbstractionError, ByteOrder, IdentifiableAbstractionElement,
4 abstraction_element, make_unique_name,
5};
6use autosar_data::{Element, ElementName, EnumItem};
7
8pub trait SignalPdu: AbstractPdu {
12 fn mapped_signals(&self) -> impl Iterator<Item = ISignalToIPduMapping> + Send + use<Self> {
14 self.element()
15 .get_sub_element(ElementName::ISignalToPduMappings)
16 .into_iter()
17 .flat_map(|mappings| mappings.sub_elements())
18 .filter_map(|elem| ISignalToIPduMapping::try_from(elem).ok())
19 }
20
21 fn map_signal(
25 &self,
26 signal: &ISignal,
27 start_position: u32,
28 byte_order: ByteOrder,
29 update_bit: Option<u32>,
30 transfer_property: TransferProperty,
31 ) -> Result<ISignalToIPduMapping, AutosarAbstractionError>;
32
33 fn map_signal_group(&self, signal_group: &ISignalGroup) -> Result<ISignalToIPduMapping, AutosarAbstractionError>;
35}
36
37pub(crate) fn verify_signal_mapping(
39 pdu: &impl SignalPdu,
40 signal: &ISignal,
41 start_position: u32,
42 byte_order: ByteOrder,
43 update_bit: Option<u32>,
44 signal_name: &String,
45) -> Result<(), AutosarAbstractionError> {
46 let length = pdu.length().unwrap_or(0);
47 let mut validator = SignalMappingValidator::new(length);
48 for mapping in pdu.mapped_signals() {
49 if let (Some(m_signal), Some(m_start_pos), Some(m_byte_order)) =
50 (mapping.signal(), mapping.start_position(), mapping.byte_order())
51 {
52 let len = m_signal.length().unwrap_or(0);
53 validator.add_signal(m_start_pos, len, m_byte_order, mapping.update_bit());
54 }
55 }
56 if !validator.add_signal(start_position, signal.length().unwrap_or(0), byte_order, update_bit) {
57 return Err(AutosarAbstractionError::InvalidParameter(format!(
58 "Cannot map signal {signal_name} to an overlapping position in the pdu"
59 )));
60 }
61
62 if let Some(signal_group) = signal.signal_group() {
65 if !pdu
66 .mapped_signals()
67 .filter_map(|mapping| mapping.signal_group())
68 .any(|grp| grp == signal_group)
69 {
70 return Err(AutosarAbstractionError::InvalidParameter(
71 "Cannot map signal to pdu, because it is part of an unmapped signal group.".to_string(),
72 ));
73 }
74 }
75 Ok(())
76}
77
78#[derive(Debug, Clone, PartialEq, Eq, Hash)]
82pub struct ISignalIPdu(Element);
83abstraction_element!(ISignalIPdu, ISignalIPdu);
84impl IdentifiableAbstractionElement for ISignalIPdu {}
85
86impl ISignalIPdu {
87 pub(crate) fn new(name: &str, package: &ArPackage, length: u32) -> Result<Self, AutosarAbstractionError> {
88 let pkg_elements = package.element().get_or_create_sub_element(ElementName::Elements)?;
89 let elem_pdu = pkg_elements.create_named_sub_element(ElementName::ISignalIPdu, name)?;
90 elem_pdu
91 .create_sub_element(ElementName::Length)?
92 .set_character_data(length.to_string())?;
93
94 Ok(Self(elem_pdu))
95 }
96
97 pub fn map_signal(
101 &self,
102 signal: &ISignal,
103 start_position: u32,
104 byte_order: ByteOrder,
105 update_bit: Option<u32>,
106 transfer_property: TransferProperty,
107 ) -> Result<ISignalToIPduMapping, AutosarAbstractionError> {
108 let signal_name = signal
109 .name()
110 .ok_or(AutosarAbstractionError::InvalidParameter("invalid signal".to_string()))?;
111
112 verify_signal_mapping(self, signal, start_position, byte_order, update_bit, &signal_name)?;
113
114 for pt in self.pdu_triggerings() {
116 let st = pt.create_signal_triggering(signal)?;
117 for pdu_port in pt.pdu_ports() {
118 if let (Ok(ecu), Some(direction)) = (pdu_port.ecu(), pdu_port.communication_direction()) {
119 st.connect_to_ecu(&ecu, direction)?;
120 }
121 }
122 }
123
124 let model = self.element().model()?;
126 let base_path = self.element().path()?;
127 let name = make_unique_name(&model, &base_path, &signal_name);
128
129 let mappings = self
130 .element()
131 .get_or_create_sub_element(ElementName::ISignalToPduMappings)?;
132
133 ISignalToIPduMapping::new_with_signal(
134 &name,
135 &mappings,
136 signal,
137 start_position,
138 byte_order,
139 update_bit,
140 transfer_property,
141 )
142 }
143
144 pub fn map_signal_group(
146 &self,
147 signal_group: &ISignalGroup,
148 ) -> Result<ISignalToIPduMapping, AutosarAbstractionError> {
149 let signal_group_name = signal_group.name().ok_or(AutosarAbstractionError::InvalidParameter(
150 "invalid signal group".to_string(),
151 ))?;
152
153 for pt in self.pdu_triggerings() {
155 let st = pt.create_signal_group_triggering(signal_group)?;
156 for pdu_port in pt.pdu_ports() {
157 if let (Ok(ecu), Some(direction)) = (pdu_port.ecu(), pdu_port.communication_direction()) {
158 st.connect_to_ecu(&ecu, direction)?;
159 }
160 }
161 }
162
163 let model = self.element().model()?;
165 let base_path = self.element().path()?;
166 let name = make_unique_name(&model, &base_path, &signal_group_name);
167
168 let mappings = self
169 .element()
170 .get_or_create_sub_element(ElementName::ISignalToPduMappings)?;
171
172 ISignalToIPduMapping::new_with_group(&name, &mappings, signal_group)
173 }
174
175 pub fn set_timing(&self, timing_spec: &IpduTiming) -> Result<(), AutosarAbstractionError> {
177 let _ = self
178 .element()
179 .remove_sub_element_kind(ElementName::IPduTimingSpecifications);
180
181 let timing_elem = self
182 .element()
183 .create_sub_element(ElementName::IPduTimingSpecifications)?
184 .create_sub_element(ElementName::IPduTiming)?;
185 if let Some(min_delay) = timing_spec.minimum_delay {
186 timing_elem
187 .create_sub_element(ElementName::MinimumDelay)?
188 .set_character_data(min_delay)?;
189 }
190 if let Some(transmission_mode_true_timing) = &timing_spec.transmission_mode_true_timing {
191 let tmtt_elem = timing_elem
192 .get_or_create_sub_element(ElementName::TransmissionModeDeclaration)?
193 .create_sub_element(ElementName::TransmissionModeTrueTiming)?;
194 Self::set_transmission_mode_timinig(tmtt_elem, transmission_mode_true_timing)?;
195 }
196 if let Some(transmission_mode_false_timing) = &timing_spec.transmission_mode_false_timing {
197 let tmtf_elem = timing_elem
198 .get_or_create_sub_element(ElementName::TransmissionModeDeclaration)?
199 .create_sub_element(ElementName::TransmissionModeFalseTiming)?;
200 Self::set_transmission_mode_timinig(tmtf_elem, transmission_mode_false_timing)?;
201 }
202
203 Ok(())
204 }
205
206 fn set_transmission_mode_timinig(
208 timing_element: Element,
209 transmission_mode_timing: &TransmissionModeTiming,
210 ) -> Result<(), AutosarAbstractionError> {
211 if let Some(cyclic_timing) = &transmission_mode_timing.cyclic_timing {
212 let ct_elem = timing_element.create_sub_element(ElementName::CyclicTiming)?;
213 ct_elem
214 .create_sub_element(ElementName::TimePeriod)?
215 .create_sub_element(ElementName::Value)?
216 .set_character_data(cyclic_timing.time_period)?;
217 if let Some(time_offset) = cyclic_timing.time_offset {
218 ct_elem
219 .create_sub_element(ElementName::TimeOffset)?
220 .create_sub_element(ElementName::Value)?
221 .set_character_data(time_offset)?;
222 }
223 }
224 if let Some(event_controlled_timing) = &transmission_mode_timing.event_controlled_timing {
225 let ect_elem = timing_element.create_sub_element(ElementName::EventControlledTiming)?;
226 ect_elem
227 .create_sub_element(ElementName::NumberOfRepetitions)?
228 .set_character_data(u64::from(event_controlled_timing.number_of_repetitions))?;
229 if let Some(repetition_period) = event_controlled_timing.repetition_period {
230 ect_elem
231 .create_sub_element(ElementName::RepetitionPeriod)?
232 .create_sub_element(ElementName::Value)?
233 .set_character_data(repetition_period)?;
234 }
235 }
236
237 Ok(())
238 }
239
240 #[must_use]
242 pub fn timing(&self) -> Option<IpduTiming> {
243 let timing_elem = self
244 .element()
245 .get_sub_element(ElementName::IPduTimingSpecifications)?
246 .get_sub_element(ElementName::IPduTiming)?;
247 let minimum_delay = timing_elem
248 .get_sub_element(ElementName::MinimumDelay)
249 .and_then(|md| md.character_data())
250 .and_then(|cdata| cdata.parse_float());
251 let transmission_mode_true_timing = timing_elem
252 .get_sub_element(ElementName::TransmissionModeDeclaration)
253 .and_then(|tmd| tmd.get_sub_element(ElementName::TransmissionModeTrueTiming))
254 .and_then(|tmtt| Self::transmission_mode_timing(&tmtt));
255 let transmission_mode_false_timing = timing_elem
256 .get_sub_element(ElementName::TransmissionModeDeclaration)
257 .and_then(|tmd| tmd.get_sub_element(ElementName::TransmissionModeFalseTiming))
258 .and_then(|tmtf| Self::transmission_mode_timing(&tmtf));
259
260 Some(IpduTiming {
261 minimum_delay,
262 transmission_mode_true_timing,
263 transmission_mode_false_timing,
264 })
265 }
266
267 fn transmission_mode_timing(timing_elem: &Element) -> Option<TransmissionModeTiming> {
269 let cyclic_timing = timing_elem.get_sub_element(ElementName::CyclicTiming).and_then(|ct| {
270 let time_period = ct
271 .get_sub_element(ElementName::TimePeriod)
272 .and_then(|tp| tp.get_sub_element(ElementName::Value))
273 .and_then(|val| val.character_data())
274 .and_then(|cdata| cdata.parse_float());
275 let time_offset = ct
276 .get_sub_element(ElementName::TimeOffset)
277 .and_then(|to| to.get_sub_element(ElementName::Value))
278 .and_then(|val| val.character_data())
279 .and_then(|cdata| cdata.parse_float());
280 time_period.map(|tp| CyclicTiming {
281 time_period: tp,
282 time_offset,
283 })
284 });
285 let event_controlled_timing = timing_elem
286 .get_sub_element(ElementName::EventControlledTiming)
287 .and_then(|ect| {
288 let number_of_repetitions = ect
289 .get_sub_element(ElementName::NumberOfRepetitions)
290 .and_then(|nr| nr.character_data())
291 .and_then(|cdata| cdata.parse_integer());
292 let repetition_period = ect
293 .get_sub_element(ElementName::RepetitionPeriod)
294 .and_then(|rp| rp.get_sub_element(ElementName::Value))
295 .and_then(|val| val.character_data())
296 .and_then(|cdata| cdata.parse_float());
297 number_of_repetitions.map(|nr| EventControlledTiming {
298 number_of_repetitions: nr,
299 repetition_period,
300 })
301 });
302
303 Some(TransmissionModeTiming {
304 cyclic_timing,
305 event_controlled_timing,
306 })
307 }
308}
309
310impl SignalPdu for ISignalIPdu {
311 fn map_signal(
312 &self,
313 signal: &ISignal,
314 start_position: u32,
315 byte_order: ByteOrder,
316 update_bit: Option<u32>,
317 transfer_property: TransferProperty,
318 ) -> Result<ISignalToIPduMapping, AutosarAbstractionError> {
319 ISignalIPdu::map_signal(self, signal, start_position, byte_order, update_bit, transfer_property)
320 }
321
322 fn map_signal_group(&self, signal_group: &ISignalGroup) -> Result<ISignalToIPduMapping, AutosarAbstractionError> {
323 ISignalIPdu::map_signal_group(self, signal_group)
324 }
325}
326
327impl AbstractPdu for ISignalIPdu {}
328
329impl AbstractIpdu for ISignalIPdu {}
330
331impl From<ISignalIPdu> for Pdu {
332 fn from(value: ISignalIPdu) -> Self {
333 Pdu::ISignalIPdu(value)
334 }
335}
336
337impl From<ISignalIPdu> for IPdu {
338 fn from(value: ISignalIPdu) -> Self {
339 IPdu::ISignalIPdu(value)
340 }
341}
342
343#[derive(Debug, Clone, PartialEq, Eq, Hash)]
347pub struct ISignalToIPduMapping(Element);
348abstraction_element!(ISignalToIPduMapping, ISignalToIPduMapping);
349impl IdentifiableAbstractionElement for ISignalToIPduMapping {}
350
351impl ISignalToIPduMapping {
352 pub(crate) fn new_with_signal(
353 name: &str,
354 mappings: &Element,
355 signal: &ISignal,
356 start_position: u32,
357 byte_order: ByteOrder,
358 update_bit: Option<u32>,
359 transfer_property: TransferProperty,
360 ) -> Result<Self, AutosarAbstractionError> {
361 let signal_mapping = mappings.create_named_sub_element(ElementName::ISignalToIPduMapping, name)?;
362 signal_mapping
363 .create_sub_element(ElementName::ISignalRef)?
364 .set_reference_target(signal.element())?;
365 signal_mapping
366 .create_sub_element(ElementName::PackingByteOrder)?
367 .set_character_data::<EnumItem>(byte_order.into())?;
368 signal_mapping
369 .create_sub_element(ElementName::StartPosition)?
370 .set_character_data(u64::from(start_position))?;
371 signal_mapping
372 .create_sub_element(ElementName::TransferProperty)?
373 .set_character_data::<EnumItem>(transfer_property.into())?;
374 if let Some(update_bit_pos) = update_bit {
375 signal_mapping
376 .create_sub_element(ElementName::UpdateIndicationBitPosition)?
377 .set_character_data(u64::from(update_bit_pos))?;
378 }
379
380 Ok(Self(signal_mapping))
381 }
382
383 pub(crate) fn new_with_group(
384 name: &str,
385 mappings: &Element,
386 signal_group: &ISignalGroup,
387 ) -> Result<Self, AutosarAbstractionError> {
388 let signal_mapping = mappings.create_named_sub_element(ElementName::ISignalToIPduMapping, name)?;
389 signal_mapping
390 .create_sub_element(ElementName::ISignalGroupRef)?
391 .set_reference_target(signal_group.element())?;
392
393 Ok(Self(signal_mapping))
394 }
395
396 #[must_use]
399 pub fn signal(&self) -> Option<ISignal> {
400 self.element()
401 .get_sub_element(ElementName::ISignalRef)
402 .and_then(|sigref| sigref.get_reference_target().ok())
403 .and_then(|signal_elem| ISignal::try_from(signal_elem).ok())
404 }
405
406 pub fn set_byte_order(&self, byte_order: ByteOrder) -> Result<(), AutosarAbstractionError> {
408 self.element()
409 .get_or_create_sub_element(ElementName::PackingByteOrder)?
410 .set_character_data::<EnumItem>(byte_order.into())?;
411 Ok(())
412 }
413
414 #[must_use]
416 pub fn byte_order(&self) -> Option<ByteOrder> {
417 self.element()
418 .get_sub_element(ElementName::PackingByteOrder)
419 .and_then(|pbo| pbo.character_data())
420 .and_then(|cdata| cdata.enum_value())
421 .and_then(|enumval| enumval.try_into().ok())
422 }
423
424 #[must_use]
427 pub fn start_position(&self) -> Option<u32> {
428 self.element()
429 .get_sub_element(ElementName::StartPosition)
430 .and_then(|sp_elem| sp_elem.character_data())
431 .and_then(|cdata| cdata.parse_integer())
432 }
433
434 #[must_use]
437 pub fn update_bit(&self) -> Option<u32> {
438 self.element()
439 .get_sub_element(ElementName::UpdateIndicationBitPosition)
440 .and_then(|uibp| uibp.character_data())
441 .and_then(|cdata| cdata.parse_integer())
442 }
443
444 pub fn set_transfer_property(&self, transfer_property: TransferProperty) -> Result<(), AutosarAbstractionError> {
446 self.element()
447 .get_or_create_sub_element(ElementName::TransferProperty)?
448 .set_character_data::<EnumItem>(transfer_property.into())?;
449 Ok(())
450 }
451
452 #[must_use]
454 pub fn transfer_property(&self) -> Option<TransferProperty> {
455 self.element()
456 .get_sub_element(ElementName::TransferProperty)
457 .and_then(|pbo| pbo.character_data())
458 .and_then(|cdata| cdata.enum_value())
459 .and_then(|enumval| enumval.try_into().ok())
460 }
461
462 #[must_use]
465 pub fn signal_group(&self) -> Option<ISignalGroup> {
466 self.element()
467 .get_sub_element(ElementName::ISignalGroupRef)
468 .and_then(|sgref| sgref.get_reference_target().ok())
469 .and_then(|siggrp_elem| ISignalGroup::try_from(siggrp_elem).ok())
470 }
471}
472
473#[derive(Debug, Clone, PartialEq)]
477pub struct IpduTiming {
478 pub minimum_delay: Option<f64>,
480 pub transmission_mode_true_timing: Option<TransmissionModeTiming>,
482 pub transmission_mode_false_timing: Option<TransmissionModeTiming>,
484}
485
486#[derive(Debug, Clone, PartialEq)]
488pub struct TransmissionModeTiming {
489 pub cyclic_timing: Option<CyclicTiming>,
491 pub event_controlled_timing: Option<EventControlledTiming>,
493}
494
495#[derive(Debug, Clone, PartialEq)]
497pub struct CyclicTiming {
498 pub time_period: f64,
500 pub time_offset: Option<f64>,
502}
503
504#[derive(Debug, Clone, PartialEq)]
506pub struct EventControlledTiming {
507 pub number_of_repetitions: u32,
509 pub repetition_period: Option<f64>,
511}
512
513pub struct SignalMappingValidator {
517 bitmap: Vec<u8>,
518}
519
520impl SignalMappingValidator {
521 #[must_use]
523 pub fn new(length: u32) -> Self {
524 Self {
525 bitmap: vec![0; length as usize],
526 }
527 }
528
529 pub fn add_signal(
534 &mut self,
535 bit_position: u32,
536 bit_length: u64,
537 byte_order: ByteOrder,
538 update_bit: Option<u32>,
539 ) -> bool {
540 let bit_position = u64::from(bit_position);
541 let first_byte = (bit_position / 8) as usize;
542 let bit_offset = bit_position % 8; let first_byte_bits; let mut first_mask;
545
546 if byte_order == ByteOrder::MostSignificantByteFirst {
547 first_byte_bits = (bit_offset + 1).min(bit_length);
553 first_mask = ((1u16 << (bit_offset + 1)) - 1) as u8;
554 if bit_offset + 1 != first_byte_bits {
555 let pos2 = bit_offset - first_byte_bits;
556 let subtract_mask = (1u8 << pos2) - 1;
557 first_mask -= subtract_mask;
558 }
559 } else {
560 first_byte_bits = (8 - bit_offset).min(bit_length); first_mask = !((1u16 << bit_offset) - 1) as u8; if bit_offset + first_byte_bits < 8 {
568 let pos2 = bit_offset + first_byte_bits;
569 let subtract_mask = !((1u8 << pos2) - 1);
570 first_mask -= subtract_mask;
571 }
572 }
573 let full_bytes = (bit_length - first_byte_bits) as usize / 8;
574 let end_bits = (bit_length - first_byte_bits) % 8;
575
576 let mut result = self.apply_mask(first_mask, first_byte);
577 result &= self.apply_full_bytes(first_byte + 1, full_bytes);
578
579 if end_bits > 0 {
581 let end_mask = if byte_order == ByteOrder::MostSignificantByteFirst {
582 !((1u8 << end_bits) - 1)
583 } else {
584 (1u8 << end_bits) - 1
585 };
586 result &= self.apply_mask(end_mask, first_byte + full_bytes + 1);
587 }
588
589 if let Some(update_bit) = update_bit {
591 let position = (update_bit / 8) as usize;
592 let bit_pos = update_bit % 8;
593 let mask = 1 << bit_pos;
594 result &= self.apply_mask(mask, position);
595 }
596
597 result
598 }
599
600 fn apply_mask(&mut self, mask: u8, position: usize) -> bool {
601 if position < self.bitmap.len() {
602 let result = self.bitmap[position] & mask == 0;
604 self.bitmap[position] |= mask;
606 result
607 } else {
608 false
609 }
610 }
611
612 fn apply_full_bytes(&mut self, position: usize, count: usize) -> bool {
613 let mut result = true;
614 if count > 0 {
615 let limit = self.bitmap.len().min(position + count);
616 for idx in position..limit {
617 result &= self.apply_mask(0xff, idx);
618 }
619 result &= limit == position + count;
621 }
622 result
623 }
624}
625
626#[cfg(test)]
629mod test {
630 use super::*;
631 use crate::{AutosarModelAbstraction, ByteOrder, SystemCategory};
632 use autosar_data::AutosarVersion;
633
634 #[test]
635 fn isignal_ipdu() {
636 let model = AutosarModelAbstraction::create("filename", AutosarVersion::Autosar_00048);
637 let package = model.get_or_create_package("/pkg").unwrap();
638 let system = package.create_system("system", SystemCategory::EcuExtract).unwrap();
639
640 let pdu = system.create_isignal_ipdu("isignal_ipdu", &package, 8).unwrap();
641 assert_eq!(pdu.name().unwrap(), "isignal_ipdu");
642 assert_eq!(pdu.length().unwrap(), 8);
643
644 let syssignal = package.create_system_signal("syssignal").unwrap();
646 let isignal = system.create_isignal("isignal", &package, 4, &syssignal, None).unwrap();
647 let mapping = pdu
648 .map_signal(
649 &isignal,
650 0,
651 ByteOrder::MostSignificantByteFirst,
652 Some(5),
653 TransferProperty::Triggered,
654 )
655 .unwrap();
656 assert_eq!(mapping.signal().unwrap(), isignal);
657 assert_eq!(mapping.start_position().unwrap(), 0);
658 assert_eq!(mapping.update_bit(), Some(5));
659 assert_eq!(mapping.byte_order().unwrap(), ByteOrder::MostSignificantByteFirst);
660 mapping.set_byte_order(ByteOrder::MostSignificantByteLast).unwrap();
661 assert_eq!(mapping.byte_order().unwrap(), ByteOrder::MostSignificantByteLast);
662 assert_eq!(mapping.transfer_property().unwrap(), TransferProperty::Triggered);
663 mapping.set_transfer_property(TransferProperty::Pending).unwrap();
664 assert_eq!(mapping.transfer_property().unwrap(), TransferProperty::Pending);
665
666 let syssignal_group = package.create_system_signal_group("syssignal_group").unwrap();
668 let signal_group = system
669 .create_isignal_group("signal_group", &package, &syssignal_group)
670 .unwrap();
671 let grouped_syssignal = package.create_system_signal("groups_syssignal").unwrap();
672 syssignal_group.add_signal(&grouped_syssignal).unwrap();
673 let grouped_isignal = system
674 .create_isignal("grouped_isignal", &package, 4, &grouped_syssignal, None)
675 .unwrap();
676 signal_group.add_signal(&grouped_isignal).unwrap();
677 assert_eq!(grouped_isignal.signal_group().unwrap(), signal_group);
678
679 let result = pdu.map_signal(
681 &grouped_isignal,
682 9,
683 ByteOrder::MostSignificantByteFirst,
684 None,
685 TransferProperty::Triggered,
686 );
687 assert!(result.is_err());
688
689 let mapping = pdu.map_signal_group(&signal_group).unwrap();
691 assert_eq!(mapping.signal_group().unwrap(), signal_group);
692
693 let _mapping = pdu
695 .map_signal(
696 &grouped_isignal,
697 9,
698 ByteOrder::MostSignificantByteFirst,
699 None,
700 TransferProperty::Triggered,
701 )
702 .unwrap();
703 }
704
705 #[test]
706 fn validate_signal_mapping() {
707 let mut validator = SignalMappingValidator::new(4);
709 let result = validator.add_signal(0, 2, ByteOrder::MostSignificantByteLast, None);
710 assert!(result);
711 assert_eq!(validator.bitmap[0], 0x03);
712
713 let mut validator = SignalMappingValidator::new(4);
715 let result = validator.add_signal(5, 10, ByteOrder::MostSignificantByteLast, None);
716 assert!(result);
717 assert_eq!(validator.bitmap[0], 0xE0);
718 assert_eq!(validator.bitmap[1], 0x7F);
719
720 let mut validator = SignalMappingValidator::new(4);
722 let result = validator.add_signal(5, 10, ByteOrder::MostSignificantByteFirst, None);
723 assert!(result);
724 assert_eq!(validator.bitmap[0], 0x3F);
725 assert_eq!(validator.bitmap[1], 0xF0);
726
727 let result = validator.add_signal(5, 10, ByteOrder::MostSignificantByteLast, None);
729 assert!(!result);
731 assert_eq!(validator.bitmap[0], 0xFF);
732 assert_eq!(validator.bitmap[1], 0xFF);
733
734 let mut validator = SignalMappingValidator::new(4);
736 let result = validator.add_signal(0, 32, ByteOrder::MostSignificantByteLast, None);
737 assert!(result);
738 assert_eq!(validator.bitmap[0], 0xFF);
739 assert_eq!(validator.bitmap[1], 0xFF);
740 assert_eq!(validator.bitmap[2], 0xFF);
741 assert_eq!(validator.bitmap[3], 0xFF);
742
743 let mut validator = SignalMappingValidator::new(4);
745 let result = validator.add_signal(7, 32, ByteOrder::MostSignificantByteFirst, None);
746 assert!(result);
747 assert_eq!(validator.bitmap[0], 0xFF);
748 assert_eq!(validator.bitmap[1], 0xFF);
749 assert_eq!(validator.bitmap[2], 0xFF);
750 assert_eq!(validator.bitmap[3], 0xFF);
751
752 let mut validator = SignalMappingValidator::new(8);
754 let result = validator.add_signal(7, 16, ByteOrder::MostSignificantByteFirst, Some(60));
755 assert!(result);
756 let result = validator.add_signal(16, 3, ByteOrder::MostSignificantByteLast, Some(61));
757 assert!(result);
758 let result = validator.add_signal(19, 7, ByteOrder::MostSignificantByteLast, Some(62));
759 assert!(result);
760 let result = validator.add_signal(26, 30, ByteOrder::MostSignificantByteLast, Some(63));
761 assert!(result);
762 let result = validator.add_signal(59, 4, ByteOrder::MostSignificantByteFirst, None);
763 assert!(result);
764 assert_eq!(validator.bitmap, [0xFF; 8]);
765 }
766
767 #[test]
768 fn ipdu_timing() {
769 let model = AutosarModelAbstraction::create("filename", AutosarVersion::Autosar_00048);
770 let package = model.get_or_create_package("/pkg").unwrap();
771 let pdu = ISignalIPdu::new("pdu_name", &package, 8).unwrap();
772
773 let timing_spec = IpduTiming {
774 minimum_delay: Some(0.1),
775 transmission_mode_true_timing: Some(TransmissionModeTiming {
776 cyclic_timing: Some(CyclicTiming {
777 time_period: 0.2,
778 time_offset: Some(0.3),
779 }),
780 event_controlled_timing: Some(EventControlledTiming {
781 number_of_repetitions: 4,
782 repetition_period: Some(0.5),
783 }),
784 }),
785 transmission_mode_false_timing: Some(TransmissionModeTiming {
786 cyclic_timing: Some(CyclicTiming {
787 time_period: 0.6,
788 time_offset: Some(0.7),
789 }),
790 event_controlled_timing: Some(EventControlledTiming {
791 number_of_repetitions: 8,
792 repetition_period: Some(0.9),
793 }),
794 }),
795 };
796 pdu.set_timing(&timing_spec).unwrap();
797 let timing_spec2 = pdu.timing().unwrap();
798 assert_eq!(timing_spec, timing_spec2);
799 }
800}