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